Có ai biết liệu có một assert
hoặc một cái gì đó tương tự có thể kiểm tra xem một ngoại lệ đã được ném trong mã đang được thử nghiệm không?
Có ai biết liệu có một assert
hoặc một cái gì đó tương tự có thể kiểm tra xem một ngoại lệ đã được ném trong mã đang được thử nghiệm không?
Câu trả lời:
<?php
require_once 'PHPUnit/Framework.php';
class ExceptionTest extends PHPUnit_Framework_TestCase
{
public function testException()
{
$this->expectException(InvalidArgumentException::class);
// or for PHPUnit < 5.2
// $this->setExpectedException(InvalidArgumentException::class);
//...and then add your test code that generates the exception
exampleMethod($anInvalidArgument);
}
}
tài liệu mong đợiException () PHPUnit
Bài viết của tác giả PHPUnit cung cấp giải thích chi tiết về kiểm tra các ngoại lệ thực tiễn tốt nhất.
$this->setExpectedException('\My\Name\Space\MyCustomException');
setExpectedException
không được dùng nữa, thay thế bằng phương thức này expectException
. :)
expectException()
. Trong khi nó có thể đã hiển nhiên đối với một số người, đó là một Gotcha cho tôi.
Bạn cũng có thể sử dụng chú thích docblock cho đến khi PHPUnit 9 được phát hành:
class ExceptionTest extends PHPUnit_Framework_TestCase
{
/**
* @expectedException InvalidArgumentException
*/
public function testException()
{
...
}
}
Đối với PHP 5.5+ (đặc biệt là với mã được đặt tên), bây giờ tôi thích sử dụng ::class
IncorrectPasswordException
nên là đủ - rằng thông điệp bằng "Wrong password for bob@me.com"
là phụ trợ. Thêm vào đó bạn muốn dành ít thời gian viết bài kiểm tra nhất có thể, và bạn bắt đầu thấy các bài kiểm tra đơn giản quan trọng như thế nào.
Nếu bạn đang chạy trên PHP 5.5+, bạn có thể sử dụng ::class
độ phân giải để lấy tên của lớp có expectException
/setExpectedException
. Điều này cung cấp một số lợi ích:
string
vì vậy nó sẽ hoạt động với bất kỳ phiên bản PHPUnit nào.Thí dụ:
namespace \My\Cool\Package;
class AuthTest extends \PHPUnit_Framework_TestCase
{
public function testLoginFailsForWrongPassword()
{
$this->expectException(WrongPasswordException::class);
Auth::login('Bob', 'wrong');
}
}
Biên dịch PHP
WrongPasswordException::class
vào
"\My\Cool\Package\WrongPasswordException"
không có PHPUnit là người khôn ngoan hơn.
Lưu ý : PHPUnit 5.2 được giới thiệu
expectException
thay thế chosetExpectedException
.
Mã dưới đây sẽ kiểm tra thông báo ngoại lệ và mã ngoại lệ.
Quan trọng: Nó sẽ thất bại nếu ngoại lệ dự kiến không được ném quá.
try{
$test->methodWhichWillThrowException();//if this method not throw exception it must be fail too.
$this->fail("Expected exception 1162011 not thrown");
}catch(MySpecificException $e){ //Not catching a generic Exception or the fail function is also catched
$this->assertEquals(1162011, $e->getCode());
$this->assertEquals("Exception Message", $e->getMessage());
}
$this->fail()
Tôi không có ý định sử dụng theo cách này mà tôi không nghĩ, ít nhất là hiện tại (PHPUnit 3.6.11); nó hoạt động như một ngoại lệ Sử dụng ví dụ của bạn, nếu $this->fail("Expected exception not thrown")
được gọi, thì catch
khối được kích hoạt và $e->getMessage()
là "Ngoại lệ dự kiến không được ném" .
fail
có lẽ thuộc về sau khối catch, không bên trong thử.
fail
không nên trong try
khối. Chính nó kích hoạt catch
khối tạo ra kết quả sai.
catch(Exception $e)
. Phương pháp này hoạt động khá tốt đối với tôi khi tôi cố gắng bắt các Ngoại lệ cụ thể:try { throw new MySpecificException; $this->fail('MySpecificException not thrown'); } catch(MySpecificException $e){}
Bạn có thể sử dụng tiện ích mở rộng assertException để xác nhận nhiều hơn một ngoại lệ trong một lần thực hiện kiểm tra.
Chèn phương thức vào TestCase của bạn và sử dụng:
public function testSomething()
{
$test = function() {
// some code that has to throw an exception
};
$this->assertException( $test, 'InvalidArgumentException', 100, 'expected message' );
}
Tôi cũng đã tạo ra một đặc điểm cho những người yêu thích mã đẹp ..
assertException
không được xác định. Tôi cũng không thể tìm thấy nó trong hướng dẫn PHPUnit.
asertException
phương pháp không phải là một phần của PHPUnit gốc. Bạn phải kế thừa PHPUnit_Framework_TestCase
lớp và thêm phương thức được liên kết trong bài viết ở trên . Các trường hợp thử nghiệm của bạn sau đó sẽ kế thừa lớp kế thừa này.
Một cách khác có thể là như sau:
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Expected Exception Message');
Hãy đảm bảo rằng lớp thử nghiệm của bạn mở rộng \PHPUnit_Framework_TestCase
.
expectException
Phương thức PHPUnit rất bất tiện vì nó chỉ cho phép kiểm tra một ngoại lệ cho mỗi phương thức kiểm tra.
Tôi đã thực hiện chức năng trợ giúp này để khẳng định rằng một số chức năng đưa ra một ngoại lệ:
/**
* Asserts that the given callback throws the given exception.
*
* @param string $expectClass The name of the expected exception class
* @param callable $callback A callback which should throw the exception
*/
protected function assertException(string $expectClass, callable $callback)
{
try {
$callback();
} catch (\Throwable $exception) {
$this->assertInstanceOf($expectClass, $exception, 'An invalid exception was thrown');
return;
}
$this->fail('No exception was thrown');
}
Thêm nó vào lớp thử nghiệm của bạn và gọi theo cách này:
public function testSomething() {
$this->assertException(\PDOException::class, function() {
new \PDO('bad:param');
});
$this->assertException(\PDOException::class, function() {
new \PDO('foo:bar');
});
}
"Các thực tiễn tốt nhất " hiện tại của PHPUnit để kiểm tra ngoại lệ dường như .. mờ nhạt ( tài liệu ).
Vì tôi muốn nhiều hơn việc expectException
triển khai hiện tại , tôi đã tạo ra một đặc điểm để sử dụng cho các trường hợp thử nghiệm của mình. Chỉ có ~ 50 dòng mã .
assert
Cú pháp chuẩnassertNotThrows
Throwable
lỗi PHP 7Tôi đã xuất bản AssertThrows
đặc điểm này cho Github và packagist để nó có thể được cài đặt với trình soạn thảo.
Chỉ để minh họa tinh thần đằng sau cú pháp:
<?php
// Using simple callback
$this->assertThrows(MyException::class, [$obj, 'doSomethingBad']);
// Using anonymous function
$this->assertThrows(MyException::class, function() use ($obj) {
$obj->doSomethingBad();
});
Khá gọn gàng?
Vui lòng xem bên dưới để biết ví dụ sử dụng toàn diện hơn:
<?php
declare(strict_types=1);
use Jchook\AssertThrows\AssertThrows;
use PHPUnit\Framework\TestCase;
// These are just for illustration
use MyNamespace\MyException;
use MyNamespace\MyObject;
final class MyTest extends TestCase
{
use AssertThrows; // <--- adds the assertThrows method
public function testMyObject()
{
$obj = new MyObject();
// Test a basic exception is thrown
$this->assertThrows(MyException::class, function() use ($obj) {
$obj->doSomethingBad();
});
// Test custom aspects of a custom extension class
$this->assertThrows(MyException::class,
function() use ($obj) {
$obj->doSomethingBad();
},
function($exception) {
$this->assertEquals('Expected value', $exception->getCustomThing());
$this->assertEquals(123, $exception->getCode());
}
);
// Test that a specific exception is NOT thrown
$this->assertNotThrows(MyException::class, function() use ($obj) {
$obj->doSomethingGood();
});
}
}
?>
public function testException() {
try {
$this->methodThatThrowsException();
$this->fail("Expected Exception has not been raised.");
} catch (Exception $ex) {
$this->assertEquals($ex->getMessage(), "Exception message");
}
}
assertEquals()
là assertEquals(mixed $expected, mixed $actual...)
, đảo ngược như trong ví dụ của bạn, vì vậy nó phải được$this->assertEquals("Exception message", $ex->getMessage());
Đây là tất cả các xác nhận ngoại lệ bạn có thể làm. Lưu ý rằng tất cả chúng là tùy chọn .
class ExceptionTest extends PHPUnit_Framework_TestCase
{
public function testException()
{
// make your exception assertions
$this->expectException(InvalidArgumentException::class);
// if you use namespaces:
// $this->expectException('\Namespace\MyException');
$this->expectExceptionMessage('message');
$this->expectExceptionMessageRegExp('/essage$/');
$this->expectExceptionCode(123);
// code that throws an exception
throw new InvalidArgumentException('message', 123);
}
public function testAnotherException()
{
// repeat as needed
$this->expectException(Exception::class);
throw new Exception('Oh no!');
}
}
Tài liệu có thể được tìm thấy ở đây .
/**
* @expectedException Exception
* @expectedExceptionMessage Amount has to be bigger then 0!
*/
public function testDepositNegative()
{
$this->account->deposit(-7);
}
Hãy thật cẩn thận "/**"
, chú ý gấp đôi "*". Chỉ viết "**" (dấu hoa thị) sẽ không thành công mã của bạn. Cũng đảm bảo rằng bạn sử dụng phiên bản cuối cùng của phpUnit. Trong một số phiên bản trước đó của phpunit @azedException Exception không được hỗ trợ. Tôi đã có 4.0 và nó không hoạt động với tôi, tôi phải cập nhật lên 5.5 https://coderwall.com/p/mklvdw/install-phastait-with-composer để cập nhật với nhà soạn nhạc.
Đối với PHPUnit 5.7.27 và PHP 5.6 và để kiểm tra nhiều ngoại lệ trong một thử nghiệm, điều quan trọng là bắt buộc thử nghiệm ngoại lệ. Sử dụng xử lý ngoại lệ một mình để khẳng định trường hợp Ngoại lệ sẽ bỏ qua việc kiểm tra tình huống nếu không có ngoại lệ xảy ra.
public function testSomeFunction() {
$e=null;
$targetClassObj= new TargetClass();
try {
$targetClassObj->doSomething();
} catch ( \Exception $e ) {
}
$this->assertInstanceOf(\Exception::class,$e);
$this->assertEquals('Some message',$e->getMessage());
$e=null;
try {
$targetClassObj->doSomethingElse();
} catch ( Exception $e ) {
}
$this->assertInstanceOf(\Exception::class,$e);
$this->assertEquals('Another message',$e->getMessage());
}
function yourfunction($a,$z){
if($a<$z){ throw new <YOUR_EXCEPTION>; }
}
đây là bài kiểm tra
class FunctionTest extends \PHPUnit_Framework_TestCase{
public function testException(){
$this->setExpectedException(<YOUR_EXCEPTION>::class);
yourfunction(1,2);//add vars that cause the exception
}
}
PhpUnit là một thư viện tuyệt vời, nhưng điểm cụ thể này là một chút bực bội. Đây là lý do tại sao chúng ta có thể sử dụng thư viện mã nguồn mở turbotesting-php có phương thức xác nhận rất thuận tiện để giúp chúng tôi kiểm tra các ngoại lệ. Nó được tìm thấy ở đây:
Và để sử dụng nó, chúng ta chỉ cần làm như sau:
AssertUtils::throwsException(function(){
// Some code that must throw an exception here
}, '/expected error message/');
Nếu mã chúng ta nhập bên trong hàm ẩn danh không ném ngoại lệ, ngoại lệ sẽ được ném.
Nếu mã chúng ta nhập bên trong hàm ẩn danh sẽ ném ra một ngoại lệ, nhưng thông báo của nó không khớp với biểu thức chính quy dự kiến, một ngoại lệ cũng sẽ bị ném.