我已经重构了一些控制器,以通过属性注入as recommended in the "best practices"使用依赖注入:
final class ZebraController extends Controller
{
/**
* @Inject
* @var AnimalClientInterface
*/
private $animalsRestClient;
public function fetchAllZebras(ServerRequestInterface $req): ResponseInterface {
// ...
}
}
我的PHP-DI配置配置为为AnimalClient
注入AnimalClientInterface
对象的实例,这在实现代码中很好,因为只有1个真实的AnimalClient
。
在单元测试中,我需要向该属性中插入MockZebraClient
。我不能像配置AnimalClient
那样简单地配置它,因为其他类可能会被类似地注释,但是需要例如MockTigerClient
进行测试。
这是我的单元测试:
class ZebraControllerTest extends TestCase
{
/** @var ZebraController */
protected $object;
public function testFetchAllZebras(): void {
// assertions here
}
}
我认为使用injectOn
method是解决此问题的正确方法,但我不知道如何配置容器以为正确的测试选择正确的模拟对象。
由于遗留代码结构,无法进行构造函数注入。为了更改Controller
的构造函数,需要重构应用程序中的所有控制器以使用DI。
答案 0 :(得分:0)
也许有一个特定于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){}}