如何模拟服务以便正确地注入它

时间:2017-03-07 10:33:56

标签: unit-testing symfony

我正在尝试在功能测试中模拟一个服务,该服务由另一个服务使用:

    $client = static::createClient();

    $stub = $this->createMock(MailService::class);
    $stub->method('sendMailToUser')->willReturn(9);
    $client->getContainer()->set('belka.auth_bundle.mail_service', $stub);
    // the *real* test should start here

如果我尝试在原始die中放置一个sendMailToUser命令,我得到的是代码停止运行,虽然我试图通过返回来模拟它9.它有什么问题?我正在测试的服务有以下声明,然后我猜测注入的服务是上面写的那个:

belka.auth_bundle.user_handler:
    class: Belka\AuthBundle\Handler\UserHandler
    arguments:
        - '@belka.auth_bundle.user_repository'
        - '@belka.auth_bundle.mail_service'
    calls:
        - [setRequest, ["@request_stack"]]
        - [setSettings, ["@belka.auth_bundle.setting_handler"]]
        - [setBodyJsonHandler, ["@belka.container_support_bundle.body_json_handler"]]
        - [setQuantityHandler, ["@belka.container_support_bundle.quantityhandler"]]

1 个答案:

答案 0 :(得分:0)

我相信Symfony正确地创建服务,所以我通常不会获得服务然后在其中进行测试(我确实有一个尝试创建几乎所有服务的冒烟测试)。

所以,如果你想获得一个' belka.auth_bundle.user_handler',我会手动创建Belka\AuthBundle\Handler\UserHandler实例,并将你的模拟作为参数之一。

对于服务中更深层次需要的服务,没有简单的方法可以模拟它们(或者让模拟器到位),但是您可以使用服务容器环境来覆盖它们。

例如,我有一个测试请求是否来自机器人的服务 - 但是在运行功能测试时,我完全用一个总是说“不是机器人”的服务替换它,通过覆盖我的' app.bot_detect.detector' /config/services_test.yml

中的服务
# set the default bot detector to a simple fake, always return false
app.bot_detect.detector:
    class: App\Services\BotDetectorNeverBot

在主config / services.yml中,该类实际上会执行检查,但测试环境的BotDetectorNeverBot类中的方法总是显示为false。

以同样的方式,您可以覆盖services_test.yml(或config_test.yml)中的belka.auth_bundle.mail_service以不发送电子邮件,而是存储内容。你必须确保你包括' * _ test.yml'文件恰当。