2017-01-05 5 views
1

次は私が働いているコントローラの単純化されたクラスです。テスト用にこれをどうやって偽装しますか?

class UserController extends Controller { 
    protected $user; 

    public function __construct(User $user) { 
     $this->user = user; 
    } 

    public function contact(ContactFormRequest $request) { 
     $user = $this->user 
      ->where('email', $request->email) 
      ->with(['orders' => function($q) { 
       $q->orderBy('created_at', 'desc') 
        ->first(); 
      }]) 
      ->first(); 

     return view('contact', ['user' => $user]); 
    } 
} 

これは、これまで私が持っているテストケースである:

class ExampleTest extends TestCase { 
    public function setUp() { 
     $this->mockUser = Mockery::mock(Model::class, User::class); 
     $this->app->instance('User', $this->mockUser); 
    } 

    public function testContactForm() { 
     $this->userMock 
      ->shouldReceive('where') 
      ->once() 
      ->with('email', '[email protected]') 
      ->andReturn(new Collection(new User, new User)); 

     $this->visit('contact-form'); 
    } 
}  

私はメモリからこれを書いてい認めますよ既存のコードを私の目の前に置くのではなく、しかし、このテストはPHPUnitに渡されます。問題は、訪問がエラーをスローし、追加の->see('something')テストが必要なことです。

私はコントローラとビューに完全で使用可能なユーザモックを与えるモックの残りが必要です。

は、私は(コードがゆがんで行く場所です)

$this->userMock 
    ->shouldReceive('where') 
    ->once() 
    ->with('email', '[email protected]') 
    ->andReturn(new Collection(new User)) 
    ->shouldReceive('with') 
    ->once(); 
    ->with(['orders' => function($q) { 
     $q->orderBy('created_at', 'desc') 
      ->first(); 
     }]) 
    ->andReturn(**something**) 
    ->shouldReceive('first') 
    ->once() 
    ->andReturn(new Collection(new User)); 

答えて

0

ORMを模擬しないでください(あなたが所有Don't mock third-party librariesとしてのみモックタイプを知っている)、それはのようになります期待しています。代わりに、テストデータベース(フィクスチャまたは afactory)を用意してください。実際にコードが必要なユーザーを見つけるようにしてください。

+0

ちょっとマキシム。理想的にはコントローラテストには実際のテストデータベースは必要ありません。 ORMをサービスクラスの中にカプセル化し、コントローラテストでそのORMをモックします。 しかし、サービス層のクラスでは、あなたが提案したことを正確に行い、ロジックが実際に動作することを確認するためにテストデータベースでテストします。コントローラテストから外れていれば、より多くの境界テストを簡単に追加できます。 – malte

関連する問題