php - mock 不从存储库(接口(interface))调用方法

标签 php testing laravel repository-pattern mockery

我正在尝试通过此测试来测试我的 Controller (如果重要的话,我正在使用 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/我使用存储库来避免将我的数据库与测试耦合。所以我有这两个额外的类(class):

<?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) 项目 Controller 测试::测试索引 Mockery\Exception\InvalidCountException:应调用 Mockery_2143809533_Dumminvoicing_Storage_Project_ProjectRepositoryInterface 中的方法 all() 恰好 1 次但被调用 0 次。

Controller 的索引方法在浏览器中工作正常:

     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”?

最佳答案

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

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

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

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

编辑

问题是你模拟了 Dumminvoicing\Storage\Project\ProjectRepositoryInterface 但它应该是 Dumminvoicing\Storage\Project\ProjectRepository

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

关于php - mock 不从存储库(接口(interface))调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20366514/

相关文章:

php - 在 Doctrine 2 中手动生成下一个序列值

PHP 转换数组 'a' , 'b' , 'c' 到 'a/b/c' , 'a/b' , 'a'

laravel - 将mysql中的日期解析为carbon对象,然后转换为本地时区

php pdo保存查询数据

php - 无法将本地 WordPress 连接到远程 MySQL 服务器

mysql - 如何扩大我的产品数据库的大小?

regex - OCaml:如何测试我自己的正则表达式库

javascript - 如何在 jest 的覆盖范围内忽略由 jest 生成的快照?

laravel - 如何测试 Laravel 资源

sql - Laravel 连接查询中的逗号分隔列值