symfony - 使用 Mink 测试时模拟服务?

标签 symfony testing mink

我现在正在开发一个应用程序,它有大量我想测试的 javascript(动态表单)。我决定使用 PHPUnit Mink + ZombieJS .

我想模拟一些与外部 API 通信的服务,但我没有找到任何资源来说明如何使用像 Mink 这样的测试框架来完成这项工作。如果我使用 Symfony 内置的 WebTestCase,我会使用像

这样的包

TestDoubleBundle ,但它不适用于像 Mink 中那样的真实世界请求。

是否有其他可用的解决方案?我想知道最好的方法是否是创建我的 API 服务的“测试”版本并配置我的测试环境以加载该服务而不是真正的服务。测试服务将使用预先确定的响应来响应各种 API 方法。最大的缺点是它不够灵活——我无法动态配置 API 方法的预期响应。

最佳答案

我在尝试弄清楚 TestDoubleBundle 的工作原理时遇到了一些困难,但实际上它非常简单。我将向您展示一个工作示例,希望它对您有所帮助。

案例研究:让我们在现实生活中http://api.postcodes.io/postcodes/{postcode} API 获取给定邮政编码的完整详细信息。如果我们提供一个不存在的邮政编码,它返回 null

下面的示例是精简版,因此您需要前往 Mocking external APIs with behat in symfony 获取完整版。

完整示例

services.yml

services:
    app.service.postcode:
        class: AppBundle\Service\PostcodeService
        arguments:
            - "@app.util.guzzle"
            - "%postcodes_api%"

    app.util.guzzle:
        class: GuzzleHttp\Client
        tags:
            - { name: test_double }

邮政编码服务

class PostcodeService
{
    private $client;
    private $apiUri;

    public function __construct(
        ClientInterface $client,
        $apiUri
    ) {
        $this->client = $client;
        $this->apiUri = $apiUri;
    }

    public function get($postcode)
    {
        return $this->getDetails($postcode);
    }

    private function getDetails($postcode)
    {
        $details = null;

        try {
            /** @var Response $response */
            $response = $this->client->request(Request::METHOD_GET, $this->apiUri.$postcode);
            /** @var Stream $body */
            $body = $response->getBody();
            $details = $body->getContents();
        } catch (ClientException $e) {
        }

        return $details;
    }
}

FeatureContext

/**
 * @param string $postcode
 *
 * @Given /^the Postcode API is available for "([^"]*)"$/
 */
public function thePostcodeApiIsAvailableFor($postcode)
{
    $postcodesApi = $this->kernel->getContainer()->getParameter('postcodes_api').$postcode;

    $response = new Response(200, [], '{"result":{"latitude":0.12345678,"longitude":-0.1234567}}');

    $this->kernel
        ->getContainer()
        ->get('app.util.guzzle.prophecy')
        ->request(Request::METHOD_GET, $postcodesApi)
        ->willReturn($response);
}

小 cucumber

  Scenario: I get full result for existent postcode.
    Given the Postcode API is available for "DUMMY POSTCODE"
    When I send a "GET" request to "/postcodes/DUMMY POSTCODE"
    Then the response status code should be 200
    And the response should contain json:
    """
    {"result":{"latitude":0.12345678,"longitude":-0.1234567}}
    """

关于symfony - 使用 Mink 测试时模拟服务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37089342/

相关文章:

symfony - Twig 从 Yaml 文件写入

testing - 如何激活登录plone测试?

ruby - 处理测试中预期的失败

php - Windows 上的 Behat - 截图

php - 如何让 behat 等待元素显示在屏幕上后再填充它?

symfony - Symfony 2:从存储库创建服务

php - 需要 Symfony 2.0 分步教程

Swift:XCTest 会修改状态吗?测试可以返回可选值的函数的约定是什么?

selenium-webdriver - 测试输入字段是否获得焦点

php - Symfony 3 类的对象无法转换为字符串