2016-10-13 2 views
1

私は、ランダムな文字列ジェネレータインターフェイスがメソッドの1つに注入されるLaravelコントローラを作成しています。次にAppServiceProviderで実装を登録しています。これは正常に動作します。Laravelでは、テスト時にサービスコンテナに別の実装を与える方法はありますか?

コントローラーは、ランダムストリングを入力として使用してデータをデータベースに保管します。私は、実際の乱数発生器を使用する際に「ABC123」はどうなるかわからないので

$this->post('/api/v1/do_things', ['email' => $this->email]) 
->seeInDatabase('things', ['email' => $this->email, 'random' => 'abc123']); 

:それはランダムなので、私はそうのような(MakesHttpRequestsを使用して)それをテストすることはできません。そこで、私はそれに対して主張できるように、常に 'abc123'を返すランダムインターフェイスの別の実装を作成しました。

質問:テスト時にこの偽の発電機にバインドするにはどうすればよいですか?は私が右のテストの前に

$this->app->bind('Random', 'TestableRandom'); 

を実行しようとしましたが、それはまだ私がAppServiceProviderに登録し、実際の発電機を使用しています。何か案は?私はそのようなことをどうやってテストするかについて完全に間違っていますか?

ありがとうございます!

答えて

1

あなたはカップルのオプションがあります。

は、実装をバインドするために、条件を使用します。

class AppServiceProvider extends ServiceProvider { 

    public function register() { 
     if($this->app->runningUnitTests()) { 
      $this->app->bind('Random', 'TestableRandom'); 
     } else { 
      $this->app->bind('Random', 'RealRandom'); 
     } 
    } 
} 

2番目のオプションは、あなたがすることを決定した場合、あなたのテストで

public function test_my_controller() { 
    // Create a mock of the Random Interface 
    $mock = Mockery::mock(RandomInterface::class); 

    // Set our expectation for the methods that should be called 
    // and what is supposed to be returned 
    $mock->shouldReceive('someMethodName')->once()->andReturn('SomeNonRandomString'); 

    // Tell laravel to use our mock when someone tries to resolve 
    // an instance of our interface 
    $this->app->instance(RandomInterface::class, $mock); 

    $this->post('/api/v1/do_things', ['email' => $this->email]) 
     ->seeInDatabase('things', [ 
      'email' => $this->email, 
      'random' => 'SomeNonRandomString', 
     ]); 
} 

をモックを使用することですモックルートに行く。嘲笑のドキュメントをチェックアウトしてください:

http://docs.mockery.io/en/latest/reference/expectations.html

+0

今の条件付き結合のアプローチと一緒に行きました。ありがとう! –

関連する問題