Php 具有持久性的Laravel模拟模型
我正在测试接收客户模型的作业。在工作中,我创建了 shopify中的客户,并将该id存储在客户模型上。然后我调用一个需要模拟的Php 具有持久性的Laravel模拟模型,php,laravel,mocking,phpunit,Php,Laravel,Mocking,Phpunit,我正在测试接收客户模型的作业。在工作中,我创建了 shopify中的客户,并将该id存储在客户模型上。然后我调用一个需要模拟的sendshopifiinvite(我不想在测试中发送电子邮件) 我的测试如下所示: /** @test */ public function a_shopify_customer_is_created_if_it_does_not_yet_exists() { $this->partialMock(User::class, function ($mock)
sendshopifiinvite
(我不想在测试中发送电子邮件)
我的测试如下所示:
/** @test */
public function a_shopify_customer_is_created_if_it_does_not_yet_exists()
{
$this->partialMock(User::class, function ($mock) {
$mock->shouldReceive('sendShopifyInvite')->once()->andReturn(new User());
});
$customer = app(User::class)->fill(
factory(User::class)->create([
'shopify_id' => null
])->toArray()
);
$this->assertNull($customer->shopify_id);
CreateCustomerJob::dispatchNow($customer);
$customer->refresh();
$this->assertNotNull($customer->shopify_id);
}
问题是我收到了以下错误:
PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'jensssen_db.mockery_0__domain__customer__models__users' doesn't exist
不可能在模拟对象中持久化数据吗?还有其他方法吗?您的问题就是因为这个。由于部分mock创建了一个新的mock对象并通过它调用了您的原始模型,因此它将采用该类basename
return $this->table ?? Str::snake(Str::pluralStudly(class_basename($this)));
我可以看到两种解决方案,我觉得没有人是完美的解决方案,它会解决你的问题。首先在User.php
模型上设置表的硬编码。这将避免调用类basename
class User {
$protected table = 'users';
}
另一种方法,我以前被迫做过(当你很难模仿某些类时)。而不是模拟您的User.php
模型,只需将相同的逻辑放在服务/代理类中并模拟它即可
class ShopifyService {
public function sendInvite(User $user)
{
...
}
}
在您的User.php
模型中,现在有了
public function sendShopifyInvite() {
resolve(ShopifyService::class)->sendInvite($this);
}
现在,您只能模拟Shopify服务,而不能修补雄辩模型的内部工作
$this->partialMock(ShopifyService::class, function ($mock) {
$user = new User();
$mock->shouldReceive('sendInvite')->with($user)->once()->andReturn($user);
});