2017-01-24 5 views
0

Ich habe einen Service-Provider, der eine CartCookie Klasse instanziiert, die ein einzigartiges Cookie zum Speichern von Einkaufswagen generiert. Es ist eine Singleton-Klasse und es wird in den Service-Container injiziert.Laravel-Cookies nicht im Service-Provider während der Unit-Tests

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 der CartCookie Klasse I für die Existenz überprüfen eines cart_id Cookie. Funktioniert perfekt, wenn Sie die Anwendung verwenden!

Mein Problem ist, dass während Unit-Tests der cart_id Cookie leer ist, aber nur wenn der Request vom Service-Provider kommt. Wenn ich beispielsweise später im Lebenszyklus die Request von einem Controller erhalte, ist der Cookie vorhanden. Hier

ist ein Beispiel für einen 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()); 
     }); 
    } 

Ich kann die Existenz sagen, wenn ich die Anfrage Cookies dd() sowohl im Service-Provider und die Steuerung, die den Warenkorb Funktionalität verarbeitet. Aus irgendeinem Grund, nur während Komponententests, enthält die Anfrage das Cookie noch nicht bei dem Dienstanbieter.

Hope das macht Sinn.

+0

Dies macht Sinn, da Diensteanbieter und dann Einheit Testanruf nach Route geladen werden ausgeführt? –

+0

@DoniiHoho Ich bin mir nicht sicher, '$ this-> call()' beginnt eine ganz neue Anfrage. – Wasim

+0

Es erstellt eine neue Anfrage und übergibt sie an die Routen, aber innerhalb der gleichen Skriptausführung, da Sie es als Singleton markiert haben, hier liegt das Problem. –

Antwort

2

Von hier aus: link

Versuche:

/** @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()); 
    }); 
} 
+0

Richtig hol ich dir jetzt. Ich war unter dem Eindruck '-> call()' war eher wie eine Ajax-Anfrage, um die Anwendung jedes Mal instanziieren, aber jetzt sehe ich anders. Ich habe den Test so modifiziert, dass er jetzt mit einer Variante Ihres Beispiels '$ cartCookie = app (CartCookie :: class); $ cartCookie-> setId ($ this-> cartCookie); app() -> instance (CartCookie :: class, $ cartCookie); 'Nicht ideal, aber der Test ist vorbei, also danke für deine Hilfe und lehre mich etwas Neues :) – Wasim

+0

Prost Kumpel, froh, dass es geholfen hat! –

Verwandte Themen