场景
函数不执行任何操作有两种可能的场景:
场景1:没有返回语句
如果您在函数中不执行任何操作,并且没有包含return
关键字,则您的函数不会执行任何操作:
public function doNothing()
{
}
场景2:使用return语句
你的函数没有执行任何操作,因为你在函数中没有进行操作并且使用了return
关键字,但没有返回任何值:
public function doNothing()
{
// Do nothing.
return;
}
其他情况
这里将不考虑以下场景的处理:
你没有返回任何东西,但执行了可以在其他对象上测试的重要操作。在这种情况下,您必须单元测试修改后对象的结果状态。
你什么也没做,但返回了一些东西,则应该对返回值进行单元测试。
探索PHP手册中的文档
对于第一种情况,PHP手册记录函数的计算表达式为 null
。在这里说道:http://php.net/manual/en/functions.returning-values.php 中的一个注释:
如果省略了return语句,那么将返回null值。
对于第二种情况,PHP手册记录函数的计算表达式也是null
。在这里说到:http://php.net/manual/en/function.return.php 中的一个注释:
如果未提供参数,则必须省略括号并返回null。[...]
结论
因此,明确记录了“什么也不做”的函数必定计算为null
。
如何测试“什么也不做”的函数
只需断言您的期望即可:
$this->assertNull( $sut->doNothing() );
这样做可以“执行”您的函数,运行它以使代码覆盖度完成所有行,并通过测试其为表达式的求值的null
值来“期望”“未发生任何事情”,如所述文档。
如何测试一个什么也不做的构造函数
然而要测试一个构造函数... 嗯...常识:构造函数的目的是什么?创建某种类型(类)的对象(实例),对吧?
所以...我更喜欢从检查$sut
是否已创建开始测试100%。这是我编写新类的代码时编写的第一项测试。这是我甚至在类存在之前编写的测试。最后,这就是构造函数的作用。红条。然后我创建类。绿条。
假设我有一个 Email
类,它接受一个字符串,并且只有在传递有效电子邮件时才会被创建,否则会引发异常。这与您的问题非常相似。一个仅“允许创建”或“通过系统崩溃拒绝创建”的构造函数。
我通常会像这样做:
public function testCreationIsOfProperClass( string $email )
{
$sut = $this->getSut( $validEmail );
$this->assertInstanceOf( Email::class, $sut );
}
public function testCreationThrowsExceptionIfEmailIsInvalid( string $invalidEmail )
{
$this->expectException( EmailException::class );
$this->getSut( $invalidEmail );
}
public function validEmailProvider() : array
{
return
[
[ 'alice@example.com' ],
[ 'bob.with-several+symbols@subdomain.another.subdomain.example.verylongTLD' ],
]
}
public function invalidEmailProvider() : array
{
return
[
[ 'missing_at_symbol' ],
[ 'charlie@cannotBeOnlyTld' ],
]
}
private function getSut( string $email ) : Email
{
return new Email( $email );
}
因为我使用 PHP 7.0 并在参数输入和返回类型中都添加了类型,所以如果创建的对象不是 Email,则 getSut() 函数将首先失败。
但即使我省略了返回类型并编写它,测试也会测试预期发生的事情:new Email('valid@example.com');
本身就是一个应该评估为类Email::class
的“某些东西”的表达式。
如何测试执行操作的构造函数
代码异味。构造函数可能不应该执行工作。如果有任何工作,只存储参数。如果构造函数“执行工作”而不仅仅是存储参数,请考虑在getter上进行延迟处理或在工厂中委托该工作。
如何测试“仅存储参数”的构造函数
就像之前一样 + 然后获取数据。
- 在第一个测试中测试创建的实例是否属于某个类。
- 然后,在另一个不同的测试中,调用一个getter来获取您在构造函数中输入的内容,即使构造函数没有做任何事情(除了存储它)。
希望这可以帮助到您。
$this->fail()
),否则只需进行一个虚假断言来通过测试($this->assertTrue(true)
)。你不需要测试是否返回了任何内容,只需专注于异常。 - Quasdunk