我目前正在开发一个 Laravel 项目,并且面临着为数据透视表设置工厂的问题。具体来说,我正在尝试为一个表创建一个工厂,作为
Order
和 Product
模型之间的枢轴。该表名为 order_product
,包含 order_id
、product_id
、quantity
和 price
等字段。
测试看起来像这样:
public function testCalculateOrderTotal(): void
{
$address = Address::factory()->create();
$client = Client::factory()->create(['address_id' => $address->id]);
$order = Order::factory()->create(['client_id' => $client->id]);
$product1 = Product::factory()->create();
$product2 = Product::factory()->create();
$orderProductData1 = [
'order_id' => $order->id,
'product_id' => $product1->id,
'quantity' => 2,
'price' => 100.00
];
$orderProductData2 = [
'order_id' => $order->id,
'product_id' => $product2->id,
'quantity' => 1,
'price' => 150.00
];
$orderProduct1 = OrderProduct::factory()->create($orderProductData1);
$orderProduct2 = OrderProduct::factory()->create($orderProductData2);
$this->orderProductRepository
->shouldReceive('findByOrder')
->with($order->id)
->once()
->andReturn(new Collection([$orderProduct1, $orderProduct2]));
$expectedTotal = ($orderProductData1['quantity'] * $orderProductData1['price']) +
($orderProductData2['quantity'] * $orderProductData2['price']);
$total = $this->orderProductService->calculateOrderTotal($order->id);
$this->assertIsFloat($total);
$this->assertEquals($expectedTotal, $total);
}
这是我正在尝试测试的服务方法
public function calculateOrderTotal($order_id): float
{
try {
$orderProducts = $this->orderProductRepository->findByOrder($order_id);
return $orderProducts->sum(fn($item) => $item->quantity * $item->price);
} catch (\Throwable $th) {
throw $th;
}
}
当我运行所有测试时(
./vendor/bin/sail exec -T laravel.test ./vendor/bin/phpunit --coverage-html=coverage/
)它不断返回:
FAILED Tests\Unit\Services\OrderProductServiceTest > calculate order total Error
Call to a member function __call() on null
at tests/Unit/Services/OrderProductServiceTest.php:56
➜ 56▕ $orderProduct1 = OrderProduct::factory()->create($orderProductData1);
57▕ $orderProduct2 = OrderProduct::factory()->create($orderProductData2);
58▕
1 个测试/Unit/Services/OrderProductServiceTest.php:56
我的
OrderProductFactory
看起来像这样:
public function definition(): array
{
return [
'order_id' => Order::factory(),
'product_id' => Product::factory(),
'quantity' => $this->faker->numberBetween(1, 10),
'price' => $this->faker->randomFloat(2, 5, 100),
];
}
我尝试更新我的 OrderProductFactory 但没有成功。
任何帮助或指导将不胜感激!
提前致谢!
这看起来并不难。但在帮助您解决这个问题之前,我自己也有几个问题:
如何实例化该
$orderProductService
变量?通过服务容器还是只是新建对象?
如何在
$orderProductRepository
类中实例化 OrderProductService
?是这样的依赖吗?
class OrderProductService
{
protected $orderProductRepository;
public function __construct(OrderProductRepository $orderProductRepository)
{
$this->orderProductRepository = $orderProductRepository;
}
}
OrderProductRepository
班。阅读[文档][1],必须这样嘲笑:$this->mock(OrderProductRepository::class, function ($mock) use ($order) {
$mock->shouldReceive('findByOrder')
->with($order->id)
->once()
->andReturn(new Collection([$orderProduct1, $orderProduct2]));
});
不过,我发现在这种情况下嘲笑是不必要的。该
findByOrder
方法很简单,无论如何都应该返回正确的结果。您只需删除此行即可。
请告诉我们,以便我们帮助您解决。