Mockery not calling method from repository (interface)

筅森魡賤 提交于 2019-12-11 05:51:15

问题


I am trying to test my controller with this test (I'm using Laravel, if that matters):

<?php
use Zizaco\FactoryMuff\Facade\FactoryMuff;

class ProjectControllerTest extends TestCase
{
    public function setUp()
    {
        parent::setUp();

        $this->mock = $this->mock('Dumminvoicing\Storage\Project\ProjectRepositoryInterface');
    }

    public function mock($class)
    {
        $mock = Mockery::mock($class);

        $this->app->instance($class, $mock);

        return $mock;
    }

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

    public function testRedirectWhenNotLogged()
    {
        Route::enableFilters();
        $response = $this->call('GET', 'projects');
        $this->assertRedirectedToAction('UserController@getLogin');
    }

    public function testAllowedWhenLogged()
    {
        Route::enableFilters();
        //Create user and log in
        $user = FactoryMuff::create('User');
        $this->be($user);
        $response = $this->call('GET', 'projects');
        $this->assertResponseOk();
    }

    public function testIndex()
    {
        $this->mock->shouldReceive('all')->once();
        $this->call('GET', 'projects');
        $this->assertViewHas('projects');
    }

}

Following these tutorials http://culttt.com/2013/07/08/creating-flexible-controllers-in-laravel-4-using-repositories/ http://culttt.com/2013/07/15/how-to-structure-testable-controllers-in-laravel-4/ I use repositories to avoid coupling my DB to the tests. So I have these 2 extra classes:

<?php
namespace Dumminvoicing\Storage\Project;

use Project;
class EloquentProjectRepository implements ProjectRepository
{
    public function all()
    {
        return Project::all();
    }

    public function find($id)
    {
        return Project::find($id);
    }
}

<?php
namespace Dumminvoicing\Storage\Project;

interface ProjectRepository
{
    public function all();
    public function find($id);
}

When I run the test, I get this error:

There was 1 error:

1) ProjectControllerTest::testIndex Mockery\Exception\InvalidCountException: Method all() from Mockery_2143809533_Dumminvoicing_Storage_Project_ProjectRepositoryInterface should be called exactly 1 times but called 0 times.

The index method of the controller works fine in the browser:

     use Dumminvoicing\Storage\Project\ProjectRepository as Project;

    class ProjectsController extends \BaseController
    {
        protected $project;

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

            $this->beforeFilter('auth');
        }
    }
/**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index()
    {
        $data['projects'] = $this->project->all();
        return View::make('projects.index', $data) ;
    }

So why is it failing in the test? Why is "all" not being called?


回答1:


If the user has to be authenticated to hit the index method, you need to authenticate each test.

The all isn't getting called because the user is being redirected.

Create an authentication method that you can call each time you need to authenticate the request.

To see why the test failing, dump out the response before you do the assert.

Edit

The problem is you've mocked Dumminvoicing\Storage\Project\ProjectRepositoryInterface but it should be Dumminvoicing\Storage\Project\ProjectRepository.

If you correct the namespace and add $this->mock->shouldReceive('all')->once(); to the testAllowedWhenLogged() method your tests will pass correctly.



来源:https://stackoverflow.com/questions/20366514/mockery-not-calling-method-from-repository-interface

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!