首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用PHP-DI注入模拟对象,用于使用PHPUnit测试控制器

使用PHP-DI注入模拟对象,用于使用PHPUnit测试控制器
EN

Stack Overflow用户
提问于 2019-01-21 13:40:33
回答 1查看 627关注 0票数 2

我重构了一些控制器,以便通过属性注入as recommended in the "best practices"使用依赖注入

代码语言:javascript
复制
final class ZebraController extends Controller
{
    /**
     * @Inject
     * @var AnimalClientInterface
     */
    private $animalsRestClient;

    public function fetchAllZebras(ServerRequestInterface $req): ResponseInterface {
        // ...
    }
}

我的PHP-DI配置被配置为为AnimalClientInterface注入AnimalClient对象的一个实例,这在实现代码中很好用,因为只有一个真正的AnimalClient

在我的单元测试中,我需要向这个属性注入一个MockZebraClient。我不能像对AnimalClient所做的那样简单地配置它,因为其他类可能有类似的注释,但例如需要一个MockTigerClient来进行测试。

这是我的单元测试:

代码语言:javascript
复制
class ZebraControllerTest extends TestCase
{
    /** @var ZebraController */
    protected $object;

    public function testFetchAllZebras(): void {
        // assertions here
    }
}

我认为使用injectOn method是解决这个问题的正确方法,但是我不知道如何配置容器来为正确的测试选择正确的模拟对象。

由于遗留的代码结构,构造函数注入是不可能的。应用程序中的所有控制器都需要重构以使用DI,以便更改Controller的构造函数。

EN

回答 1

Stack Overflow用户

发布于 2019-01-23 00:09:53

也许有一个特定于PHP-DI的答案,但我不熟悉它。在你的例子中,定义构造函数似乎也是不被允许的。鉴于此,您可以使用静态伪装构造函数进行测试,它允许访问设置内部状态:

代码语言:javascript
复制
<?php
class A {
    private $b;

    public static function construct($b) {
        $a = new A();
        $a->b = $b;
        return $a;
    }
}

class B {

}

$a = A::construct(new B());
var_dump($a);

返回:

object(A)#2 (1) { "b":"A":private=> object(B)#1 (0) {} }

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54284024

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档