当前位置: 动力学知识库 > 问答 > 编程问答 >

php - Laravel cookies not available in service provider during unit testing

问题描述:

I have a service provider which instantiates a CartCookie class which generates a unique cookie for saving shopping carts. It's a singleton class and it's injected into the service container.

CartCookieServiceProvider.php

public function boot(Request $request)

{

$this->app->singleton(CartCookie::class, function ($app) use ($request) {

return new CartCookie($request);

});

}

CartCookie.php

use App\Cart;

use Illuminate\Http\Request;

class CartCookie

{

private $id;

private $request;

function __construct(Request $request)

{

$this->request = $request;

if ($request->cookie('cart_id')) {

$this->id = $request->cookie('cart_id');

} else {

$this->id = $this->generateUniqueCartId();

}

}

public function id()

{

return $this->id;

}

private function generateUniqueCartId()

{

do {

$id = md5(time() . 'cart' . rand(100000000000000, 9999999999999999));

} while (Cart::find($id));

return $id;

}

}

In the CartCookie class I check for the existence of a cart_id cookie. Works perfectly fine when using the application!

My issue is that during unit tests, the cart_id cookie is empty, but only when the Request comes from the service provider. If I obtain the Request from a Controller later on in the lifecycle for example, the cookie is present.

Here is an example of a test:

/** @test */

public function get__store_checkout__checkout_displays_database_cart_correctly()

{

$cart = $this->createDatabaseCart();

$cookie = ['cart_id' => Crypt::encrypt($this->cartCookie)];

$response = $this->call('get', route('root.store.checkout'), [

'seller_id' => $cart->seller->id,

], $cookie);

$cart->seller->items()->each(function ($item) use ($response) {

$this->assertContains($beat->item, $response->getContent());

});

}

I can tell the existence when I dd() the request cookies in both the service provider and the controller that handles the cart functionality. For some reason, only during unit tests, the request doesn't contain the cookie yet in the service provider.

Hope this makes sense.

网友答案:

From here: link

Try:

/** @test */
public function get__store_checkout__checkout_displays_database_cart_correctly()
{
    $cart = $this->createDatabaseCart();

    $cookie = ['cart_id' => Crypt::encrypt($this->cartCookie)];

    //@TODO you must get the current request
    //@TODO you must set $cookie to $request
    //Or simply find a way to create the CartCookie you need using the $cookie from above
    $cartCookie = new CartCookie($request);

    //hopefully will swap the CartCookie::class instance
    app()->instance(CartCookie::class, $cartCookie);

    //Now that you have the CartCookie
    $response = $this->call('get', route('root.store.checkout'), [
        'seller_id' => $cart->seller->id,
    ], $cookie);

    $cart->seller->items()->each(function ($item) use ($response) {
        $this->assertContains($beat->item, $response->getContent());
    });
}
分享给朋友:
您可能感兴趣的文章:
随机阅读: