Laravel 嘲讽

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25724391/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 10:03:59  来源:igfitidea点击:

Laravel mockery

unit-testinglaravelmockery

提问by Robert Austin

I am trying to set up the simplest of tests in my controller but, as with most things Laravel, there are no decent tutorials to demonstrate the simple stuff.

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

I can run a simple test (in a file called UserControllerTest) like this:

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

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

This calls the /users route and passes in an array users.

这将调用 /users 路由并传入一个用户数组。

I want to do the same with Mockery but how?

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

If I try this:

如果我试试这个:

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

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

}

I get an error that "Static method Mockery_0_users::all does not exist on this mock object.

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

Why not? I am mocking User which extends Ardent and in turn extends Eloquent. Why does ::all not exist for the mock?

为什么不?我正在嘲笑扩展 Ardent 并反过来扩展 Eloquent 的 User。为什么 ::all 不存在于模拟中?

BTW, these are the set-up functions for Mockery:

顺便说一句,这些是 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;
}

采纳答案by Alexandre Butynski

You can't directly mock an Eloquent class. Eloquent is not a Facade and your User model neither. There is a bit of magic in Laravel but you can't do things like that.

您不能直接模拟 Eloquent 类。Eloquent 不是 Facade,您的 User 模型也不是。Laravel 有一些魔法,但你不能做那样的事情。

If you want to mock your User class, you have to inject it in the controller constructor. The repository pattern is a good approach if you want to do that. There is a lot of articles about this pattern and Laravel on Google.

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

Here some pieces of code to show you how it could look like :

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

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

}

If it seems to be too much structuration for your project you can just call a real database in your tests and don't mock your model classes... In a classic project, it just works fine.

如果你的项目看起来结构化太多,你可以在你的测试中调用一个真正的数据库,不要模拟你的模型类......在一个经典项目中,它工作正常。

回答by Mahmoud Zalt

This functionis part of a project called apiato.ioyou can use it to mock any class in Laravel, even facade, basically anything that can be resolved with the IoC, which is almost all classes if you are using proper dependency injection:

这个函数是一个项目的一部分,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;
}