Я тестирую метод 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
, ожидаемые или нет.
Что правильно правильно проверить мои три сценария?
Поскольку PHPUnit не продолжает проверку после ожидания исключения, подход, показанный в вопросе, является ошибочным, потому что PHPUnit обертывает тест в регулярном блоке try/catch, поэтому, как только генерируется исключение, остальные утверждения в тесте метод игнорируются. Кроме того, метод \PHPUnit_Framework_TestCase::setExpectedException
работает так, как ожидалось: тест проходит тогда и только тогда, когда \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);
}
@expectedException
.
Вы должны держать свои тесты короткими и чистыми. Таким образом, вы должны обязательно разделить свой тест на несколько тестов, которые проверяют различные аспекты вашего метода.
Я также рекомендую вам писать тесты в стиле BDD. Поэтому вы должны проверить ожидаемое поведение, например:
public function shouldReturnTrueForAdmin() {
//given
$validAdmin = ........;
//when
$result = $this->User->validateAdmin($validAdmin);
//then
$this->assertTrue($result);
}
Тестирование исключений в этом стиле затруднено в PhpUnit.
Вы можете попробовать CatchException от узо лакомства:
public function shouldFailIfNotAdmin() {
//given
$anotherUserRole = ........;
//when
CatchException::when($this->User)>validateAdmin($anotherUserRole);
//then
CatchException::assertThat()->isInstanceOf("NotAnAdminException");
}