【问题标题】:Mockery not calling method from repository (interface)嘲弄不从存储库调用方法(接口)
【发布时间】:2013-12-20 10:00:29
【问题描述】:

我正在尝试用这个测试来测试我的控制器(我正在使用 Laravel,如果这很重要的话):

<?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');
    }

}

按照这些教程 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/ 我使用存储库来避免将我的数据库耦合到测试。所以我有这两个额外的类:

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

当我运行测试时,我得到这个错误:

有 1 个错误:

1) ProjectControllerTest::testIndex Mockery\Exception\InvalidCountException:应该调用 Mockery_2143809533_Dumminvoicing_Storage_Project_ProjectRepositoryInterface 中的方法 all() 正好 1 次,但调用了 0 次。

控制器的 index 方法在浏览器中可以正常工作:

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

那么为什么它在测试中失败了?为什么不调用“all”?

【问题讨论】:

    标签: php testing laravel repository-pattern mockery


    【解决方案1】:

    如果用户必须通过身份验证才能使用index 方法,则需要对每个测试进行身份验证。

    all 没有被调用,因为正在重定向用户。

    创建一个authentication 方法,您可以在每次需要对请求进行身份验证时调用该方法。

    要查看测试失败的原因,请在执行断言之前转储响应。

    编辑

    问题是你嘲笑了Dumminvoicing\Storage\Project\ProjectRepositoryInterface,但它应该是Dumminvoicing\Storage\Project\ProjectRepository

    如果您更正命名空间并将$this-&gt;mock-&gt;shouldReceive('all')-&gt;once(); 添加到testAllowedWhenLogged() 方法中,您的测试将正确通过。

    【讨论】:

    • 哇!菲利普布朗本人的回答!你的教程太棒了!!关于这个......过滤器不是应该不起作用吗?这就是为什么我放 Route::enableFilters();在其他两个测试中......那条线会影响所有测试吗?
    • 我认为没有发生重定向,我已将断言更改为 $this->assertRedirectedToAction('UserController@getLogin');它失败并显示“断言 Illuminate\Http\Response 对象 (...) 是类“Illuminate\Http\RedirectResponse”的实例失败。”
    猜你喜欢
    • 2017-09-01
    • 2015-01-26
    • 2016-07-12
    • 2019-06-26
    • 2019-08-03
    • 2018-04-05
    • 2020-09-06
    • 1970-01-01
    • 2017-06-28
    相关资源
    最近更新 更多