Symfony/PHPUnit 模拟服务

2022-01-25 00:00:00 php symfony phpunit

我正在使用 PHPUnit 为 Symfony 编写功能测试,但我的模拟不起作用.不过,我可能误解了它们的工作原理.

I'm writing functional tests for Symfony w/ PHPUnit, and my mocks aren't working. It's possible I misunderstood how they work though.

在我的单元测试的 setUp() 方法中,我有以下代码:

In my unit test's setUp() method I have this code:

...
// Create a stub
$stub = $this->getMockBuilder('\ApiBundle\Util\WordPressBridge')
    ->disableOriginalConstructor()
    ->getMock();

// Configure the stub.
$user = new WordPressUser();
$user->setUsername('dummy');
$stub->expects($this->any())
     ->method('checkCredentials')
     ->will($this->returnValue(true));
$stub->expects($this->any())
     ->method('getUser')
     ->will($this->returnValue($user));
...

在我的 Symfony 应用程序中,我定义了一个服务:

In my Symfony application, I have a service defined:

services:
    api.wp_bridge:
        class: ApiBundleUtilWordPressBridge
        arguments: [@service_container]

据我了解,mock 应该替换真正的 WordPressBridge,但事实并非如此.我原来的还在用.我错过了什么吗?

It's my understanding that the mock should be replace the real WordPressBridge, but that isn't what's happening. My original is still being used. Am I missing something?

推荐答案

据我了解,mock 应该替换真正的 WordPressBridge,但事实并非如此.我原来的还在用.我错过了什么吗?

It's my understanding that the mock should be replace the real WordPressBridge, but that isn't what's happening. My original is still being used. Am I missing something?

基本上你必须在 Symfony 容器中以某种方式替换你的服务.

Basically you have to replace your service somehow in the Symfony Container.

如果您进行功能测试",那么您可能应该为 "test" 环境创建测试虚拟"服务,该服务将覆盖原始服务.你可以这样做:

If you doing "functional testing" then probably you should create test "dummy" service for "test" env which will overwrote original one. You can do something like that:

在 src/YourBundle/Resources/config/services.yml

services:
    api.wp_bridge:
        class: %api.wp_bridge.class%
        arguments: [@service_container]

在 app/config/config.yml

parameters:
    api.wp_bridge.class: "ApiBundleUtilWordPressBridge"

在 app/config/config_test.yml

parameters:
    api.wp_bridge.class: "ApiBundleUtilTestWordPressBridge"

然后功能测试将使用 "ApiBundleUtilTestWordPressBridge" - 因为它是在 "test" 环境中执行的.

Then functional test will use "ApiBundleUtilTestWordPressBridge" - cause it is executed in "test" env.

您可以尝试模拟容器并将其传递给测试内核,但是如果没有其他一些模拟库(在纯 PHPUnit 中),这可能会很痛苦.

You can try to mock container and pass it to test kernel but this can be painfull without some other mocking lib (in pure PHPUnit).

我个人使用 phpspec2 进行单元"测试,其中模拟很容易 :) 和一些接受标准"" 我正在使用的东西 behat 和 貂

Personally I am using phpspec2 for "unit" testing where mocking is just easy :) and for some "acceptance criteria" stuff I am using behat and mink

相关文章