Pregunta

I am trying to test this function in a Laravel controller:

/**
     * 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'));

   }

My (wrong) test looks like this:

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();
    }

The problem is, basically, that Ardent sets $project to false when the validation fails, but it also sets errors on that same object, that can be retreived with ->errors()->all().

I'm quite lost trying to find out what to return in the mock.

Note: The constructor injects the model:

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

        $this->beforeFilter('auth');
    }
¿Fue útil?

Solución

– Edited by following comments in answer –

If I'm understanding what you are trying to do properly, you could do this:

  • Mock the create() method to return a mocked Project.
  • Mock the save() method to return false.
  • Mock a MessageBag instance, which is the object that errors() would return. This mock should have a mocked all() method.
  • Make the mocked errors() method to return the MessageBag mock.

Assuming $this->mock is a mock of the Project class here:

// 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();
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top