我有以下课程:
class Testclass
{
public WebshopappApiClient $client;
public function __construct(Webshop $webshop)
{
$this->client = app()->make(WebshopappApiClient::class, ['webshop' => $webshop]);
}
public function callTestMethod()
{
// This should be Mock value std empty class
dd($this->client->shipments);
}
}
与以下服务提供商合作:
<?php
namespace App\Providers;
use App\Webshop;
use Illuminate\Support\ServiceProvider;
class WebshopappApiClientServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind(\WebshopappApiClient::class, function ($app, $params): \WebshopappApiClient {
/** @var Webshop $webshop */
$webshop = $params['webshop'];
$key = $webshop->key;
$value = $webshop->value;
return new \WebshopappApiClient($key, $value);
});
}
}
我想在我的测试中使用 Mockery 覆盖
$this->client->shipments
中对 Testclass
的调用:
public function testShipWithTracking(): void
{
$mockClient = Mockery::mock(\WebshopappApiClient::class);
$mockClient->shipments = Mockery::mock('stdClass');
app()->instance(\WebshopappApiClient::class, $mockClient);
$webshop = new Webshop([
'key' => 'test',
'value' => 'test',
]);
$testClass = new Testclass($webshop);
// Still returns the real object instead of the mocked std class?
$testClass->callTestMethod();
}
看来嘲笑实际上并不起作用。
dd($this->client->shipments)
仍然返回原始对象而不是空的 std 类。如何确保该服务绑定被模拟对象覆盖而不更改类的构造函数?
根本目标是模拟来自此 api 客户端类的所有 API 响应,而不更改 Testclass 的构造函数。这个类在遗留代码中被调用了数十次。
这个问题的答案是,只有 Facade 实现可以通过 app()->inject(...) 调用来覆盖。这是一个具体的实现,应该直接用模拟对象注入