【发布时间】:2019-11-27 22:03:12
【问题描述】:
我有点怀疑要注入什么。鉴于此代码:
class A
{
public function getSomething()
{
return 'something';
}
}
class TestMe
{
/**
* @var A
*/
private $a;
public function __construct($a)
{
$this->a = $a;
}
public function greetings()
{
return 'Hello, '.$this->a->getSomething();
}
}
我的测试 A:
function testA()
{
$a = new class() {
public function getSomething()
{
return 'aAnonimus';
}
};
$sut = new TestMe($a);
$this->assertEquals($sut->greetings(), 'Hello, aAnonimus');
}
testB,相同但带有模拟:
function testA()
{
$a = $this->createMock(A::class);
$a->method('getSomething')->willReturn('bMockery');
$sut = new TestMe($a);
$this->assertEquals($sut->greetings(), 'Hello, bMockery');
}
在第一个测试中,我只是注入了一个普通对象。 但第二种方式更像是 Phpunit 的方式:使用模拟对象。
问题是,在很长一段时间内,哪一个赢了?我发现第一个更方便,第二个测试,你必须知道依赖的类名(否则你不能创建一个模拟)
【问题讨论】:
-
任何人“知道依赖的类名”有什么问题?
-
因为如果它改变了,测试也应该。
-
hmm... 换一种看法如何:您需要更改某些依赖项-> 在测试用例中设置它-> 在源代码中更改它?我的意思是 2 点:a)您通常不会在您的课程中使用随机依赖项,是吗?你需要特定的、可预期的和可靠的; b)是的,源代码和测试代码具有某种相关性,它们相互遵循(没有人想要不相关的测试)。并且从技术上考虑类型提示的依赖项——无论如何你都需要扩展匿名类 === 'know the class name'。
-
从长远来看,phpunit 方式绝对是最好的选择。您可以将
expects添加到它以确保实际调用它。您可以将with添加到它以确保使用正确的变量调用它。如果函数被多次调用,您可以使用willReturnOnConsecutiveCalls使其返回不同的值。
标签: unit-testing mocking phpunit