class Testme()
{
    public function testMe ($a)
    {
        if ($a == 1)
        {
            throw new Exception ('YAY');
        }
    }
}
所以它很容易测试,如果它抛出异常
/**
 * @expectedException Exception
 */
public function test()
{
    new Testme(1);
}
但如果它什么都没做呢?
public function test()
{
    new Testme(2);
 ?? ? ? ? ?
}
Xav*_*ero 14
对于函数什么都不做,您有两种可能的方案:
您的函数不执行任何操作,因为您不在其中执行操作,并且您不在其中包含return关键字:
public function doNothing()
{
    // Do nothing.
}
你的函数什么都不做,因为你不执行它的行动和你做包括了return在它的关键字没有表达任何返回值:
public function doNothing()
{
    // Do nothing.
    return;
}
我将不再处理以下情况:
除了执行可以在其他对象上测试的重要操作之外,您不返回任何内容的情况.在这种情况下,您必须对修改对象的结果状态进行单元测试.
除了返回某些内容之外什么都不做的情况,那么你应该对返回值进行单元测试.
对于第一种情况,PHP手册记录了函数的计算表达式null.它在这里说:http://php.net/manual/en/functions.returning-values.php在一个注释中:
如果省略返回,则返回值NULL.
对于第二种情况,PHP手册记录了funcion的计算表达式null.它在这里说:http://php.net/manual/en/function.return.php在一个注释中:
如果未提供参数,则必须省略括号并返回NULL.[...]
因此,清楚地记载了"无所事事"的功能必须进行评估null.
只是断言你的期望:
$this->assertNull( $sut->doNothing() );
通过这种方式,你可以"运用"你的功能,你可以使用它来使代码覆盖完成所有的行,并且通过测试null其评估值作为表达式来"预期""没有发生" ,如文档所述.
不过要测试一个构造函数......好吧......常识:构造函数的目的是什么?创建某种类型的类吧?
所以...我更喜欢通过检查$sut已经创建的单元测试来启动100%的单元测试.这是我在做新课时所做的第一次测试.这是我在课程存在之前编写的测试.最后,这就是构造函数的用途.红酒吧.然后我创建了这个类.绿色酒吧.
假设我有一个Email带字符串的类,只有在传递有效的电子邮件时才会创建,否则抛出异常.这与你的问题非常相似.一种构造函数,只是"允许创建"或"通过爆炸系统来否认它".
我通常会这样做:
//-------------------------------------------------//
// Tests                                           //
//-------------------------------------------------//
/** @dataProvider validEmailProvider **/
public function testCreationIsOfProperClass( string $email )
{
    $sut = $this->getSut( $validEmail );
    $this->assertInstanceOf( Email::class, $sut );
}
/** @dataProvider invalidEmailProvider **/
public function testCreationThrowsExceptionIfEmailIsInvalid( string $invalidEmail )
{
    $this->expectException( EmailException::class );
    $this->getSut( $invalidEmail );
}
//-------------------------------------------------//
// Data providers                                  //
//-------------------------------------------------//
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' ],
    ]
}
//-------------------------------------------------//
// Sut creators                                    //
//-------------------------------------------------//
private function getSut( string $email ) : Email
{
    return new Email( $email );
}
当我使用PHP 7.0并且我将类型放在任何地方时,无论是输入参数还是返回类型,如果创建的对象不是电子邮件,则getSut()函数将首先失败.
但即使我写了省略返回类型,测试也会测试它预期会发生什么:new Email( 'valid@example.com' );它本身就是一个表达式,它应该评估为类的"某事" Email::class.
代码味道.构造函数可能不应该工作.如果有的话,只需存储参数.如果构造函数"工作"而不是存储参数,则考虑在getter上进行延迟处理,或者在工厂中委派该工作.
就像之前一样+然后获取数据.
希望这会有所帮助.
Nic*_*rth 12
在 PHPUnit 7.2+ 中,您还可以使用 TestCase::expectNotToPerformAssertions()
public function test()
{
    // ...
    $this->expectNotToPerformAssertions();
}
这与@doesNotPerformAssertions注释具有相同的行为。
如今,最佳实践是针对这些情况进行注释:
/**
 * @doesNotPerformAssertions
 */
public function testSomething()
{
    $someService = new SomeObject();
    $someService->shallNotFail();
}
这是不可能的。添加return语句并断言结果。
class Testme()
{
    public function testMe ($a)
    {
        if ($a == 1)
        {
            throw new Exception ('YAY');
        }
        return true;
    }
}
进而
$object = new Testme();
$this->assertTrue($object->testMe(2));