轉發:我對單元測試,嘲笑,ioc容器等是相當新的。因此,可能有一個簡單的答案,但我在我的智慧結局,因爲我可以沒有看到它。Laravel控制器單元測試嘲笑模型不叫
我想測試一個控制器的行爲。該動作應該在模型上調用一個函數,返回一個模型。在測試中,我嘲笑模型,將其綁定到IOC容器。我通過它的構造函數將依賴注入到控制器中。然而,不知何故,模擬並沒有被發現和調用,而是調用了該模型的實時版本。 (我可以說,正在生成日誌。)
首先,我的單元測試。創建模擬,告訴它期望一個函數,將其添加到ioc容器,調用路由。
public function testHash(){
$hash = Mockery::mock('HashLogin');
$hash->shouldReceive('checkHash')->once();
$this->app->instance('HashLogin', $hash);
$this->call('GET', 'login/hash/c3e144adfe8133343b37d0d95f987d87b2d87a24');
}
其次,我的控制器構造函數的依賴注入。
public function __construct(User $user, HashLogin $hashlogin){
$this->user = $user;
$this->hashlogin = $hashlogin;
$this->ip_direct = array_key_exists("REMOTE_ADDR",$_SERVER) ? $_SERVER["REMOTE_ADDR"] : null;
$this->ip_elb = array_key_exists("HTTP_X_FORWARDED_FOR",$_SERVER) ? $_SERVER["HTTP_X_FORWARDED_FOR"] : null;
$this->beforeFilter(function()
{
if(Auth::check()){return Redirect::to('/');}
});
}
然後我的控制器方法。
public function getHash($code){
$hash = $this->hashlogin->checkHash($code);
if(!$hash){
return $this->badLogin('Invalid Login');
}
$user = $this->user->getFromLegacy($hash->getLegacyUser());
$hash->cleanup();
$this->login($user);
return Redirect::intended('/');
}
控制器方法被調用正確,但它似乎沒有看到我的模擬,所以它調用實際模型的功能。這導致模擬的期望失敗,並且對數據庫進行檢查,這是不可取的。
預先感謝您! -Wally
編輯:我也在另一個測試中得到同樣的問題,雖然這一個使用Laravel的內置在外牆。
測試:
public function testLoginSuccessfulWithAuthTrue(){
Input::shouldReceive('get')->with('username')->once()->andReturn('user');
Input::shouldReceive('get')->with('password')->once()->andReturn('1234');
Auth::shouldReceive('attempt')->once()->andReturn(true);
$user = Mockery::mock('User');
$user->shouldReceive('buildRBAC')->once();
Auth::shouldReceive('user')->once()->andReturn($user);
$this->call('POST', 'login');
$this->assertRedirectedToRoute('index');
}
在控制器方法:
public function postIndex(){
$username = Input::get("username");
$pass = Input::get('password');
if(Auth::attempt(array('username' => $username, 'password' => $pass))){
Auth::user()->buildRBAC();
}else{
$user = $this->user->checkForLegacyUser($username);
if($user){
$this->login($user);
}else{
return Redirect::back()->withInput()->with('error', "Invalid credentials.");
}
}
return Redirect::intended('/');
}
我收到的錯誤:
Mockery\Exception\InvalidCountException: Method get("username") from Mockery_5_Illuminate_Http_Request should be called exactly 1 times but called 0 times."
同樣,我知道方法正確調用,它似乎嘲笑沒有被使用。
再次感謝您的任何建議。
編輯2
解決了它。我曾嘗試在一個地方或另一個地方使用命名空間,但顯然Mockery :: mock和app-> instance()都需要完全命名空間名稱。這個問題在其他測試中並沒有發生,所以我甚至沒有考慮過它。我希望這可以幫助別人,因爲這一段時間讓我感到頭痛。
相關代碼固定:
$hash = Mockery::mock('App\Models\Eloquent\HashLogin');
...
$this->app->instance('App\Models\Eloquent\HashLogin', $hash);
我不能回答我自己的,由於代表限制6小時的問題,但在那個時候這樣做。
-Wally