使用 PHP 匿名类进行测试和模拟

Kev*_*vin 2 php phpunit unit-testing symfony php-7

我正在尝试使用匿名类测试和模拟一段代码。这是代码:

<?php

namespace App\Service;

use Symfony\Contracts\HttpClient\HttpClientInterface;

class FetchPromoCodeService
{
    private $client;

    public function __construct(HttpClientInterface $client)
    {
        $this->client = $client;
    }

    public function getPromoCodeList(): array
    {
        $response = $this->client->request(
            'GET', 'https://xxxxxxxxx.mockapi.io/test/list'
        );

        return $response->toArray();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的测试类:

<?php

namespace App\Tests\Service;

use App\Service\FetchPromoCodeService;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\JsonResponse;

class FetchPromoCodeServiceTest extends TestCase
{

    public function testGetPromoCodeList()
    {
        $fetchPromoCodeService = new class () extends FetchPromoCodeService {
            public $client;

            public function __construct($client)
            {
                $this->client = (new JsonResponse(['a' => 1, 'b' => 2]))->getContent();
                parent::__construct($client);
            }
        };

        $result = $fetchPromoCodeService->getPromoCodeList();

        $this->assertIsArray($result);
    }
}
Run Code Online (Sandbox Code Playgroud)

我需要测试该getPromoCodeList()方法,所以我想模拟 http 调用。测试的目的是确保我们将结果调用转换为 php 数组。

但我的问题是构造函数FetchPromoCodeService。当我执行命令时出现这个错误。

ArgumentCountError:函数 class@anonymous::__construct() 的参数太少,第 14 行 /var/www/html/tests/Service/FetchPromoCodeServiceTest.php 中传递了 0 个参数,而预期正好为 1 个

我知道它正在等待类型的参数,HttpClientInterface但我知道有一种方法可以覆盖它,因为我只想模拟client属性。我只是不记得我该怎么做。

我怎样才能在 php 和匿名类中做到这一点?

Phi*_*nke 5

尽管您可以使用匿名类来实现您想要的目的,但 Symfony HTTP 客户端附带的模拟客户端可能是更简单的解决方案:

<?php

namespace App\Tests\Service;

use App\Service\FetchPromoCodeService;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpClient\MockHttpClient;
use Symfony\Component\HttpClient\Response\MockResponse;

final class FetchPromoCodeServiceTest extends TestCase
{
    public function testGetPromoCodeList()
    {
        $client = new MockHttpClient([new MockResponse(json_encode(['a' => 1, 'b' => 2]))]);

        $result = (new FetchPromoCodeService($client))->getPromoCodeList();

        self::assertIsArray($result);
    }
}
Run Code Online (Sandbox Code Playgroud)