Laravel - 如何使用 Mockery 来模拟服务绑定?

问题描述 投票:0回答:1

我有以下课程:

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 的构造函数。这个类在遗留代码中被调用了数十次。

php laravel dependency-injection laravel-9
1个回答
0
投票

这个问题的答案是,只有 Facade 实现可以通过 app()->inject(...) 调用来覆盖。这是一个具体的实现,应该直接用模拟对象注入

© www.soinside.com 2019 - 2024. All rights reserved.