php - 如何模拟 Laravel 模型以进行课程测试?
问题描述
我有这样的课:
<?php
use App\Models\Product;
class ProductSearcher
{
public function getPrintedProducts( $releasedOnly = true ) {
$products = Product::with('productVersion','productVersion.tag')
->where('printed', 1);
if ($releasedOnly)
$products->where('released', 1);
$products = $products->get();
return $products;
}
}
在我的测试中,我写
// ... some other testing ...
public function testChossingCorrectingProductFromProductVersionIds()
{
$productSearcher= new ProductSearcher;
$productMock = \Mockery::mock( 'App\Models\Product' );
$productMock->shouldReceive( 'with->where->where->get' )->andReturn( [] );
$this->assertEmpty( $productSearcher->getPrintedProducts( true ) );
}
// ... some other testing ...
我运行测试但得到:
PHP Fatal error: Cannot redeclare Mockery_1_App_Models_Product::mockery_init()
请问我做错了什么?或者测试这个功能的正确方法是什么?(这是一个单元测试,不应该太重,所以连接到测试数据库不是一个选项)
解决方案
imo 测试这种功能的最佳方法是在内存中设置一个测试数据库。然后,当它为空时,在测试期间使用工厂创建几个模型。然后你就知道你有多少数据库记录以及什么样的记录。然后只需检查类是否返回正确的。
第二种方法是使用 IoC - 重构 ProductSearcher 并将 Product 模型类作为依赖项传递。然后,您可以在测试期间轻松模拟课程。
但我还有另一个问题 - 为什么你首先创建 ProductSearcher 类?使用范围会不会更容易?
如果您想使用工厂,请执行以下操作:
首先 - 定义工厂。如果需要,用于主模型及其关系。为方便起见,您可以使用状态在记录中创建预定义的值集。https://laravel.com/docs/8.x/database-testing#defining-model-factories
第二 - 创建一个测试。我的例子:
public function testChossingCorrectingProductFromProductVersionIds() { $productSearcher= new ProductSearcher(); $notPrinted = Product::factory->count(2)->create([ 'printed' => false, 'released' => false ]); $printed = Product::factory->count(3)->create([ 'printed' => true, 'released' => false ]); $releasedNotPrinted = Product::factory->count(4)->create([ 'printed' => false, 'released' => true ]); $releasedPrinted = Product::factory->count(5)->create([ 'printed' => true, 'released' => true ]); $this->assertCount(8, $productSearcher->getPrintedProducts( false ) ); $this->assertCount(5, $productSearcher->getPrintedProducts( true ));
}
一些开发人员对“一个测试,一个断言”过于敏感,但我不是其中之一,如您所见:D
推荐阅读
- unity3d - 在 Unity 5.6.1 中找不到碰撞层?
- android - 在 RecyclerView 中滚动时如何减小 AppBarLayout 的大小?
- regular-language - 正规语言(自动机理论)
- nginx - nginx: [emerg] "XXX" 指令在 /etc/nginx/conf.d/XXX.conf:7 中重复
- php - 从 REST API 获取发布的数据
- database - 带有数据库的 Intellij Idea 错误
- ionic-framework - Mobile First 8 应用程序在后台运行一段时间后未重新连接
- ms-access - Microsoft 访问存储日期/时间信息的格式是什么?
- r - 如何计算犯罪密度?
- python - Python len() 不起作用,但 __len__ 对持有 numpy 数组的类起作用