3

コントローラーのアクションをテストしようとしています。そのアクションはモデルの関数を呼び出し、モデルを返す必要があります。テストでは、モデルをモックし、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('/');
}

コントローラー メソッドは正しく呼び出されていますが、私のモックが表示されていないようで、実際のモデルの関数を呼び出しています。これにより、モックの期待が失敗し、望ましくない DB に対するチェックが行われます。

別のテストでも同じ問題が発生していますが、これは Laravel のビルトイン Facade を使用しています。

テスト:

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."

繰り返しますが、メソッドが適切に呼び出されていることはわかっていますが、モックが使用されていないようです。

4

1 に答える 1

4

解決しました。私は以前に名前空間で遊んでみましたが、どうやらMockery::mockと の両方にapp->instance()完全に名前空間が必要です。この問題は他のテストでは発生していなかったので、考えたこともありませんでした。これはしばらくの間私の頭を悩ませたので、これが他の誰かに役立つことを願っています.

関連するコードが修正されました:

$hash = Mockery::mock('App\Models\Eloquent\HashLogin');
$this->app->instance('App\Models\Eloquent\HashLogin', $hash);
于 2014-04-24T15:32:25.510 に答える