2014-05-20 4 views
0

게시물과 블로그 클래스가 있습니다.Laravel & Mockery - 유닛 테스팅 관계형 데이터

아래에서 볼 수 있듯이 Post 클래스는 Blog 클래스에 따라 다릅니다. 다음과 같이

public function index(Blog $blog) { 
    $posts = $this->post->all()->where('blog_id', $blog->id)->orderBy('date')->paginate(20); 
    return View::make($this->tmpl('index'), compact('blog', 'posts')); 
} 

이 액션에 대한 URL은 :이 테스트하기 위해 노력하고있어

http://example.com/blogs/[blog_name]/posts 

,하지만 난 문제로 실행 해요.

가 여기 내 테스트 클래스 PostTestController이다 : 나는 GET 호출을 테스트 할 수 있습니다 ... 어떻게

public function setUp() { 
    parent::setUp(); 
    $this->mock = Mockery::mock('Eloquent', 'Post'); 
} 

public function tearDown() { 
    Mockery::close(); 
} 

public function testIndex() { 

    $this->mock->shouldReceive('with')->once(); 

    $this->app->instance('Post', $this->mock); 

    // get posts url 
    $this->get('blogs/blog/posts'); //this is where I'm stuck. 

    $this->assertViewHas('posts'); 
} 

질문은 이것이다, 때 얻을 자체가 데이터를 기반으로 변수 출력이 포함입니까? 이것을 올바르게 테스트하려면 어떻게해야합니까?

답변

0

먼저 코드에 오류가 있습니다. all()을 삭제할 수 있습니다.

$posts = $this->post 
    ->where('blog_id', $blog->id) 
    ->orderBy('date') 
    ->paginate(20); 

둘째, 내가 단위 테스트 경로 모델을 결합하는 방법을 잘 모르는 것 같아요, 그래서 public function index(Blog $blog) 그 라인을 따라 public function index($blogSlug)에 다음 할 $this->blog->where('slug', '=', $blogSlug)->first() 또는 뭔가를 변경할 것입니다.

세 번째로, 단지 m::mock('Post')을 수행하십시오. 묵시적인 비트를 삭제하십시오. 이 문제가 발생하면 m::mock('Post')->makePartial()을 실행하십시오.

절대적으로 모든 것을 테스트하고 싶다면 테스트는 대략 다음과 같습니다.

use Mockery as m; 

/** @test */ 
public function index() 
{ 
    $this->app->instance('Blog', $mockBlog = m::mock('Blog')); 
    $this->app->instance('Post', $mockPost = m::mock('Post')); 
    $stubBlog = new Blog(); // could also be a mock 
    $stubBlog->id = 5; 
    $results = $this->app['paginator']->make([/* fake posts here? */], 30, 20); 
    $mockBlog->shouldReceive('where')->with('slug', '=', 'test')->once()->andReturn($stubBlog); 
    $mockPost->shouldReceive('where')->with('blog_id', '=', 5)->once()->andReturn(m::self()) 
     ->getMock()->shouldReceive('orderBy')->with('date')->once()->andReturn(m::self()) 
     ->getMock()->shouldReceive('paginate')->with(20)->once()->andReturn($results); 

    $this->call('get', 'blogs/test/posts'); 
    // assertions 
} 

이이 장치에 (이 경우, 블로그 및 포스트 모델은 데이터베이스 층이다) 데이터베이스 계층에 연결되는 계층을 테스트 어렵다는 것을 좋은 예로서 역할을한다. 대신 테스트 데이터베이스를 설정하고 더미 데이터로 시드 한 다음 테스트를 실행하거나 리포지토리 클래스에 데이터베이스 논리를 추출하여 컨트롤러에 주입하고 모델 대신 모의합니다.