我正在测试User::validateAdmin()
模型方法,该方法可以做三件事:
true
false
NotAnAdminException
到目前为止,我有这个:
$result = $this->User->validateAdmin($validAdmin);
$espected = true;
$this->assertEquals($result, $espected);
$result = $this->User->validateAdmin($disabledAdmin);
$espected = false;
$this->assertEquals($result, $espected);
$this->setExpectedException('NotAnAdminException');
$result = $this->User->validateAdmin($anotherUserRole);
$espected = null;
$this->assertEquals($result, $espected);
$this->setExpectedException(null);
...但这会使PHPUnit忽略所有后续的NotAnAdminException
用法,无论是否预期。
正确测试我的三个场景的正确性是什么?
答案 0 :(得分:2)
你应该保持你的测试简短和干净。因此,您绝对应该将测试分成多个测试,以测试方法的不同方面。
我也鼓励你以BDD风格编写测试。所以你应该测试预期的行为,例如:
public function shouldReturnTrueForAdmin() {
//given
$validAdmin = ........;
//when
$result = $this->User->validateAdmin($validAdmin);
//then
$this->assertTrue($result);
}
在PhpUnit中很难测试此样式的异常。
您可以尝试CatchException中的ouzo goodies:
public function shouldFailIfNotAdmin() {
//given
$anotherUserRole = ........;
//when
CatchException::when($this->User)>validateAdmin($anotherUserRole);
//then
CatchException::assertThat()->isInstanceOf("NotAnAdminException");
}
答案 1 :(得分:0)
正如PHPUnit doesn't continue test after expecting an exception所解释的那样,问题中显示的方法存在缺陷,因为PHPUnit将测试包装在常规的try / catch块中,因此只要抛出异常,测试方法中的其余断言就是忽略。除此之外,\PHPUnit_Framework_TestCase::setExpectedException
方法按预期工作:当且仅当抛出给定异常时,测试才会通过。
最干净的方法是用不同的方法分割断言:
public function testvalidateAdminValid(){
$validAdmin = ........;
$result = $this->User->validateAdmin($validAdmin);
$espected = true;
$this->assertEquals($result, $espected);
}
public function testvalidateAdminExpired(){
$disabledAdmin = ........;
$result = $this->User->validateAdmin($disabledAdmin);
$espected = false;
$this->assertEquals($result, $espected);
}
public function testvalidateAdminNotAnAdmin(){
$anotherUserRole = ........;
$this->setExpectedException('NotAnAdminException');
$this->User->validateAdmin($anotherUserRole);
}
如果您希望将所有相关测试都放在同一方法中,则必须自己模拟setExpectedException
,例如:
try{
$result = $this->User->validateAdmin($anotherUserRole);
$this->fail('Failed to throw NotAnAdminException');
}catch(NotAnAdminException $e){
$this->assertEmpty($result);
}