为了账号安全,请及时绑定邮箱和手机立即绑定

如何测试与第三方 API 交互的服务?

如何测试与第三方 API 交互的服务?

PHP
慕田峪9158850 2022-08-05 10:42:00
我有以下服务要测试:namespace App\Service;class ApiManager{   public function getProjects()   {      $projects = $this->pager->fetchAll(                $this->client->api('projects'),                'all',                [['simple' => true]]      );   }}该服务使用用于 PHP 的 Gitlab API 捆绑包。因此,$projects中的数据如下所示:[   0 => [           'id' => 1,           'title' => 'Project #1',           'description' => 'Project description...'        ],   1 => [           'id' => 2,           'title' => 'Project #2',           'description' => 'Project description...'        ],]当然,我不想用来自API的真实数据进行测试。如何模拟从 getProjects 中的 HTTP 请求返回的数据?
查看完整描述

3 回答

?
慕姐4208626

TA贡献1852条经验 获得超7个赞

将 外部化到您自己的服务中,例如 ProjectService,并将其注入到 ApiManager 中。public function getProjects()

创建两个版本的 ProjectService:ProjectService 和 ProjectMockService,首先当然用于生产,2nd 应该返回模拟值(无论你在这里需要什么)。

然后为生产和测试环境维护 services.yaml。根据活动环境的不同,将注入正确版本的 ProjectService。


查看完整回答
反对 回复 2022-08-05
?
POPMUISE

TA贡献1765条经验 获得超5个赞

理想情况下,您的应用程序应将来自第三方 API 的数据转换为包含在您自己的应用程序中的模型。然后,应用程序应仅使用此模型的实例,而不是从 API 返回的数据。

这种抽象级别使测试更容易,因为只有一个地方使用API数据:在某种映射中。服务类可以从 API 获取数据,然后映射器将响应转换为域对象。

为了回答你的实际问题,我不会真正测试对API的HTTP调用。测试网络调用会使测试套件变慢,并且在没有网络连接的环境中会失败。相反,我会使用 API 中预先保存的或虚拟响应来测试映射器。如果 API 在某个时候开始以不同的“形状”返回数据,则代码中只有一个位置需要更改(映射层)。


查看完整回答
反对 回复 2022-08-05
?
慕的地10843

TA贡献1785条经验 获得超8个赞

在这种特定情况下,您不需要任何花哨的东西。您已经拥有依赖项(我希望您通过以下方式接收)。如果是这种情况,请继续模拟单元测试您的方法。Pager__construct()$this->pager->fetchAll()


如下所示:


ApiManagerTest.php


class ApiManagerTest extends TestCase

{

    private $pager;


    private $apiManager;


    public function setUp(): void

    {

        $this->pager = $this->prophesize(Pager::class);


        // Notice we pass the mocked `pager` object here

        $this->apiManager = new ApiManager(

            $this->pager->reveal()

        );

    }


    public function testGetProjects(): void

    {

        // Given

        $projects = $this->givenTwoProjectsExist();


        $this->pager->getProjects(

            'projects',

            'all',

            [['simple' => true]]

        )

        ->shouldBeCalledOnce()

        ->willReturn($projects);


        // When

        $result = $this->apiManager->fetchAll();


        // Then

        self::assertEquals($projects, $result);

    }

}

您可以在此处阅读有关“给定,何时,然后”结构的更多信息:https://thephp.website/en/issue/clean-tests-with-php-and-phpunit/


查看完整回答
反对 回复 2022-08-05
  • 3 回答
  • 0 关注
  • 154 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信