2017-01-24 70 views
0

我有一個服務提供商,它實例化了一個CartCookie類,該類生成一個用於保存購物車的獨特cookie。這是一個單例類,它被注入到服務容器中。Laravel餅乾在單元測試期間不在服務提供商處提供

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; 
    } 
} 

CartCookie類我查了cart_id cookie的存在。使用應用程序時工作得很好!

我的問題是,在單元測試期間,cart_id cookie爲空,但僅當Request來自服務提供商時。例如,如果我在生命週期的後期從控制器獲取Request,則存在Cookie。

下面是測試的一個例子:

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

我可以告訴大家的存在,當我dd()請求餅乾在兩個服務提供商和處理車功能的控制器。出於某種原因,只有在單元測試期間,請求中不包含服務提供者中的cookie。

希望這是有道理的。

+0

這是有道理的,因爲服務提供者首先加載,然後執行單元測試呼叫路由? –

+0

@DoniiHoho我不確定,'$ this-> call()'正在啓動一個全新的請求。 – Wasim

+0

它創建一個新的請求並將它傳遞給路由,但在同一個腳本執行中,因爲你已經將它標記爲單例,這就是問題所在。 –

回答

2

從這裏:link

嘗試:

/** @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

右我現在得到你。我印象中' - > call()'更像是一個ajax請求,它會每次都實例化應用程序,但現在我看到了其他情況。我已經修改了測試,現在使用示例'$ cartCookie = app(CartCookie :: class)的變體來傳遞測試。 $ cartCookie-> SETID($這個 - > cartCookie);應用程序() - >實例(CartCookie :: class,$ cartCookie);'不理想,但測試通過,所以感謝您的幫助,並教我新東西:) – Wasim

+0

乾杯隊友,很高興它幫助! –