【问题标题】:Laravel mockeryLaravel 嘲讽
【发布时间】:2014-11-01 16:20:02
【问题描述】:

我正在尝试在我的控制器中设置最简单的测试,但是与 Laravel 的大多数东西一样,没有像样的教程来演示简单的东西。

我可以像这样运行一个简单的测试(在一个名为 UserControllerTest 的文件中):

public function testIndex()
{      
    $this->call('GET', 'users');
    $this->assertViewHas('users');
}

这会调用 /users 路由并传入数组 users。

我想对 Mockery 做同样的事情,但是怎么做呢?

如果我试试这个:

public function testIndex()
{
  $this->mock->shouldReceive('users')->once();

  $this->call('GET', 'users');

}

我收到一条错误消息:“此模拟对象上不存在静态方法 Mockery_0_users::all。

为什么不呢?我在嘲笑用户,它扩展了 Ardent 并反过来扩展了 Eloquent。为什么模拟的 ::all 不存在?

顺便说一句,这些是 Mockery 的设置函数:

public function setUp()
{
  parent::setUp();

  $this->mock = $this->mock('User');
}

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

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

  return $mock;
}

【问题讨论】:

    标签: unit-testing laravel mockery


    【解决方案1】:

    您不能直接模拟 Eloquent 类。 Eloquent 不是门面,你的用户模型也不是。 Laravel 有一点魔力,但你不能这样做。

    如果你想模拟你的 User 类,你必须将它注入到控制器构造函数中。如果您想这样做,存储库模式是一个很好的方法。 Google 上有很多关于这种模式和 Laravel 的文章。

    这里有一些代码向您展示它的外观:

    class UserController extends BaseController {
    
        public function __construct(UserRepositoryInterface $users)
        {
            $this->users = $users;
        }
    
        public function index()
        {
            $users = $this->users->all();
            return View::make('user.index', compact('users'));
        }
    
    }
    
    class UserControllerTest extends TestCase
    {
    
        public function testIndex()
        {
            $repository = m::mock('UserRepositoryInterface');
            $repository->shouldReceive('all')->andReturn(new Collection(array(new User, new User)));
            App::instance('UserRepositoryInterface', $repository);
    
            $this->call('GET', 'users');
        }
    
    }
    

    如果您的项目似乎过于结构化,您可以在测试中调用一个真实的数据库,不要模拟您的模型类...在经典项目中,它可以正常工作。

    【讨论】:

    • 感谢您的回复。我现在很想远离 Mockery,但是如果我创建一个数据库会发生什么,它工作正常,投入生产等等,然后用户报告一个错误。如果我不模拟并运行一些测试,我不会在实际用户数据库中插入和更新数据吗?
    • 您必须为您的testing 环境创建特定配置。只需创建一个带有其他数据库配置的app/config/testing/database.php 文件,该数据库仅在您运行测试时使用。如果您想了解更多详细信息,请阅读文档:laravel.com/docs/configuration#environment-configuration.
    【解决方案2】:

    这个function 是一个名为apiato.io 的项目的一部分,你可以用它来模拟 Laravel 中的任何类,甚至是外观,基本上任何可以用 IoC 解决的东西,如果你使用正确的话,它几乎是所有类依赖注入:

    /**
     * Mocking helper
     *
     * @param $class
     *
     * @return  \Mockery\MockInterface
     */
    public function mock($class)
    {
        $mock = Mockery::mock($class);
        App::instance($class, $mock);
    
        return $mock;
    }
    

    【讨论】:

      猜你喜欢
      • 2022-12-05
      • 2016-01-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-20
      • 1970-01-01
      • 2016-02-22
      • 2014-04-19
      相关资源
      最近更新 更多