繁体   English   中英

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

[英]Inject mock objects using PHP-DI for testing controllers with PHPUnit

我已经重构了一些控制器, 以按照“最佳实践”中的建议通过属性注入来使用依赖项注入:

final class ZebraController extends Controller
{
    /**
     * @Inject
     * @var AnimalClientInterface
     */
    private $animalsRestClient;

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

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

在单元测试中,我需要将MockZebraClient注入此属性。 我不能像对AnimalClient那样简单地对其进行配置,因为其他类可能会被类似地注释,但是需要例如MockTigerClient进行测试。

这是我的单元测试:

class ZebraControllerTest extends TestCase
{
    /** @var ZebraController */
    protected $object;

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

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

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

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

<?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){}}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM