如何模拟 Laravel Eloquent 模型的静态方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37456518/
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 13:52:29  来源:igfitidea点击:

How to mock static methods of a Laravel Eloquent model?

unit-testinglaraveleloquentmockery

提问by Zed

I have in my code a line like this:

我的代码中有这样一行:

ModelName::create($data);

where ModelName is just an Eloquentmodel. Is there a way to mock this call inside a unit test? I tried with:

其中 ModelName 只是一个Eloquent模型。有没有办法在单元测试中模拟这个调用?我试过:

$client_mock = \Mockery::mock('Eloquent','App\Models\ModelName');
$client_mock->shouldReceive('create')
            ->with($data)->andReturns($returnValue);

but it doesn't work.

但它不起作用。

回答by Marcin Nabia?ek

You should do something like this:

你应该做这样的事情:

$client_mock = \Mockery::mock('overload:App\Models\ModelName');
$client_mock->shouldReceive('create')->with($data)->andReturn($returnValue);

We are using overload:because you don't want to pass mock to some class, but you want to use it also in case it's hard-coded into some classes.

我们使用它overload:是因为您不想将模拟传递给某个类,但您也想使用它以防它被硬编码到某些类中。

In addition to your test class (just before class) you should add:

除了您的测试类(就在 之前class)之外,您还应该添加:

/**
 * @runTestsInSeparateProcesses
 * @preserveGlobalState disabled
 */

to avoid errors that this class was already loaded (it might work without it in single test but when you are running multiple tests probably it won't).

以避免此类已加载的错误(在单个测试中没有它可能会工作,但当您运行多个测试时可能不会)。

You might read Mocking hard dependenciesfor details about it.

您可以阅读Mocking hard dependencies以了解有关它的详细信息。

UPDATE

更新

In some cases it might be not possible to mock classes using this method. In those cases you can create a normal mock (without overload) and inject it to the service container like so:

在某些情况下,可能无法使用此方法模拟类。在这些情况下,您可以创建一个普通的模拟(没有overload)并将其注入服务容器,如下所示:

App::instance('\App\Models\ModelName', $client_mock);