I'm working on a ecommerce website using Laravel 5.2 and I've run into a problem when testing the part of the app that uses cookies.
The idea is that a Cart is created for every user that visits the website. Here is my Cart model:
class Cart extends Model
{
protected $fillable = [
'cookie_token',
];
/**
* Returns the Cart for the current user.
*
* @return Cart
*/
public static function current()
{
$cookie_token = Cookie::get('cookie_token') ?: self::generateCookieToken();
return self::getCartByCookieToken($cookie_token);
}
/**
* Returns the Cart for the given cookie_token or creates a new one.
*
* @param $cookie_token
* @return Cart
*/
protected static function getCartByCookieToken($cookie_token)
{
$cart = Cart::where('cookie_token', $cookie_token)
->first();
if (empty($cart)) {
$cart = Cart::create(['cookie_token' => $cookie_token]);
Cookie::queue('cookie_token', $cookie_token, 525600);
}
return $cart;
}
}
So when I call Cart::current() I get the row from the database with cookie_token retrieved from the cookie or a new row is generated and the cookie is saved.
It works well in the browser but not in the tests. Here's the simplest test I have:
class CartTest extends TestCase
{
use DatabaseTransactions;
/** @test */
public function an_item_can_be_added_to_the_cart()
{
$product = factory(App\Product::class)->create();
Cart::current()->addItem($product);
$this->assertEquals(1, Cart::current()->count());
$this->assertEquals($product->id, Cart::current()->items()->first()->product_id);
}
The tests fail and if I disable the DatabaseTransactions trait, I can see in the database that 3 rows are created with 3 different values of the field cookie_token.
It seems that cookies are not saved during testing, so when I call Cart::current(), a new row is created each time, rather than fetching the one created with the same call a line before.
I'm not an expert on tests, so I'm probably missing something. I guess I should maybe mock it somehow? How can I test code that uses cookies?
Aucun commentaire:
Enregistrer un commentaire