如何使用Mockery测试使用Ardent模型的控制器?

时间:2013-12-09 17:09:03

标签: testing laravel mocking mockery ardent

我试图在Laravel控制器中测试这个功能:

/**
     * Store a newly created resource in storage.
     *
     * @return Response
     */
    public function store()
    {
        $project = $this->project->create(Input::all());
        if ( $errors = $project->errors()->all() ) {
           return Redirect::route('projects.create')
           ->withInput()
           ->withErrors($errors);

       }
       return Redirect::route('projects.index')
       ->with('flash', Lang::get('projects.project_created'));

   }

我的(错误的)测试看起来像这样:

public function testStoreFails()
    {
        $this->mock->shouldReceive('create')
            ->once()
            ->andReturn(Mockery::mock(array(
                    false,
                    'errors' => array()
                    )));
        $this->call('POST', 'projects');
        $this->assertRedirectedToRoute('projects.create');
        $this->assertSessionHasErrors();
    }

问题基本上是,当验证失败时,Ardent将$ project设置为false,但它也会在同一个对象上设置错误,可以使用 - > errors() - > all()进行检索。

我很遗憾试图找出在模拟中返回什么。

注意:构造函数注入模型:

public function __construct(Project $project)
    {
        $this->project = $project;

        $this->beforeFilter('auth');
    }

1 个答案:

答案 0 :(得分:1)

- 在回答中通过以下评论进行编辑 -

如果我理解你正在尝试做什么,你可以这样做:

  • 模拟create()方法以返回模拟的Project
  • 模拟save()方法返回false。
  • 模拟MessageBag实例,这是errors()将返回的对象。这个模拟应该有一个模拟的all()方法。
  • 使模拟的errors()方法返回MessageBag模拟。

假设$this->mockProject类的模拟:

// given that $this->mock = Mockery::mock('Project')

public function testStoreFails()
{
    // Mock the create() method to return itself
    $this->mock->shouldReceive('save')->once()->andReturn(false); 

    // Mock MessageBag and all() method
    $errors = Mockery::mock('Illuminate\Support\MessageBag');
    $errors->shouldReceive('all')->once()->andReturn(array('foo' => 'bar'));

    // Mock errors() method from model and make it return the MessageBag mock
    $this->mock->shouldReceive('errors')->andReturn($errors);

    // Proceed to make the post call
    $this->call('POST', 'projects');
    $this->assertRedirectedToRoute('projects.create');
    $this->assertSessionHasErrors();
}