如何模拟 laravel 5 中模型的创建方法?
How can I mock the create method on a model in laravel 5?
我正在为我的 laravel 5 应用程序编写单元测试。在一个测试中,我调用了一个函数,需要验证它是否在被测函数中调用了另一个模型的静态 create
方法。
我不想将任何资源持久保存到数据库中。
我创建了一个模拟对象,指定了期望,并将其绑定到应用程序实例,但是当调用 create
时,应用程序尝试 运行 SQL 而不是模拟对象拦截的函数调用。
public function testLogCreation() {
$this->log = Mockery::mock('App\Models\Log');
$this->log->shouldReceive('create')->once();
$this->app->instance('App\Models\Log',$this->log);
echo get_class($this->app['App\Models\Log']); // output: Mockery_2_App_Models_Log
}
There was 1 error
SQLSTATE[23503]: Foreign key violation: 7 ERROR: insert or update on table "logs" violates foreign key constraint....
我也尝试了 $this->log->shouldReceive('save')->once();
因为我观察到静态 create
函数调用 public save
函数,但我认为我没有创建模拟期望在 log
.
的右侧实例上
如果这无法实现,对替代策略有什么建议吗?
谢谢!
众所周知,静态方法在单元测试中很难处理。行
$this->app->instance('App\Models\Log', $this->log);
在应用程序中安装您的 mock 以进行依赖注入,但依赖注入仅对 Laravel 创建的对象起作用。静态方法实际上 没有 底层对象,因此它不适用。
您可以使用的一种方法是具有 createLog
方法的工厂或服务接口。这个接口然后有一个具体的 class ,它使用静态方法创建日志模型(或者更好的是,消除了对静态方法的需要)。然后,您可以轻松地在测试中模拟该接口并验证是否调用了 createLog
。
有关类似问题的精彩答案,请参阅此处:Laravel Dependency Injection: When do you have to? When can you mock Facades? Advantages of either method?
您可以通过服务容器实例化一个 Eloquent 模型并在您的生产代码中对其进行 运行 save()(而不是使用 create()方法)。
$log = $this->app->make('App\Models\Log')->fill($array);
$log->save();
这允许您模拟实际对象而不是外观或静态方法。然后你可以像你的例子一样使用 Mockery,只模拟 'fill' 和 'save' 方法。
我正在为我的 laravel 5 应用程序编写单元测试。在一个测试中,我调用了一个函数,需要验证它是否在被测函数中调用了另一个模型的静态 create
方法。
我不想将任何资源持久保存到数据库中。
我创建了一个模拟对象,指定了期望,并将其绑定到应用程序实例,但是当调用 create
时,应用程序尝试 运行 SQL 而不是模拟对象拦截的函数调用。
public function testLogCreation() {
$this->log = Mockery::mock('App\Models\Log');
$this->log->shouldReceive('create')->once();
$this->app->instance('App\Models\Log',$this->log);
echo get_class($this->app['App\Models\Log']); // output: Mockery_2_App_Models_Log
}
There was 1 error
SQLSTATE[23503]: Foreign key violation: 7 ERROR: insert or update on table "logs" violates foreign key constraint....
我也尝试了 $this->log->shouldReceive('save')->once();
因为我观察到静态 create
函数调用 public save
函数,但我认为我没有创建模拟期望在 log
.
如果这无法实现,对替代策略有什么建议吗?
谢谢!
众所周知,静态方法在单元测试中很难处理。行
$this->app->instance('App\Models\Log', $this->log);
在应用程序中安装您的 mock 以进行依赖注入,但依赖注入仅对 Laravel 创建的对象起作用。静态方法实际上 没有 底层对象,因此它不适用。
您可以使用的一种方法是具有 createLog
方法的工厂或服务接口。这个接口然后有一个具体的 class ,它使用静态方法创建日志模型(或者更好的是,消除了对静态方法的需要)。然后,您可以轻松地在测试中模拟该接口并验证是否调用了 createLog
。
有关类似问题的精彩答案,请参阅此处:Laravel Dependency Injection: When do you have to? When can you mock Facades? Advantages of either method?
您可以通过服务容器实例化一个 Eloquent 模型并在您的生产代码中对其进行 运行 save()(而不是使用 create()方法)。
$log = $this->app->make('App\Models\Log')->fill($array);
$log->save();
这允许您模拟实际对象而不是外观或静态方法。然后你可以像你的例子一样使用 Mockery,只模拟 'fill' 和 'save' 方法。