ไม่มีใครรู้ว่ามีassert
หรือสิ่งที่สามารถทดสอบว่าข้อยกเว้นถูกโยนลงในรหัสการทดสอบหรือไม่
ไม่มีใครรู้ว่ามีassert
หรือสิ่งที่สามารถทดสอบว่าข้อยกเว้นถูกโยนลงในรหัสการทดสอบหรือไม่
คำตอบ:
<?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);
}
}
expectException () เอกสาร PHPUnit
บทความผู้เขียน PHPUnitให้คำอธิบายโดยละเอียดเกี่ยวกับการทดสอบข้อยกเว้นวิธีปฏิบัติที่ดีที่สุด
$this->setExpectedException('\My\Name\Space\MyCustomException');
expectException()
ในขณะที่บางคนอาจจะเห็นได้ชัด แต่ก็เป็นgotchaสำหรับฉัน
คุณยังสามารถใช้คำอธิบายประกอบ docblockจนกว่าจะวางจำหน่าย PHPUnit 9:
class ExceptionTest extends PHPUnit_Framework_TestCase
{
/**
* @expectedException InvalidArgumentException
*/
public function testException()
{
...
}
}
สำหรับ PHP 5.5+ (โดยเฉพาะกับโค้ดเนมสเปซ) ตอนนี้ฉันชอบใช้ ::class
IncorrectPasswordException
ควรจะเพียงพอ - ว่าข้อความเท่ากับ"Wrong password for bob@me.com"
เสริม เพิ่มไปที่คุณต้องการใช้เวลาน้อยที่สุดในการเขียนแบบทดสอบและคุณเริ่มเห็นว่าการทดสอบแบบง่ายมีความสำคัญเพียงใด
หากคุณกำลังทำงานบน PHP 5.5+ คุณสามารถใช้::class
ความละเอียดที่จะได้รับชื่อของคลาสที่มี/expectException
setExpectedException
สิ่งนี้ให้ประโยชน์หลายประการ:
string
ดังนั้นมันจะทำงานกับ PHPUnit รุ่นใดก็ได้ตัวอย่าง:
namespace \My\Cool\Package;
class AuthTest extends \PHPUnit_Framework_TestCase
{
public function testLoginFailsForWrongPassword()
{
$this->expectException(WrongPasswordException::class);
Auth::login('Bob', 'wrong');
}
}
คอมไพล์ PHP
WrongPasswordException::class
เข้าไป
"\My\Cool\Package\WrongPasswordException"
ไม่มี PHPUnit เป็นคนฉลาด
หมายเหตุ : PHPUnit 5.2 แนะนำ แทนสำหรับ
expectException
setExpectedException
รหัสด้านล่างจะทดสอบข้อความข้อยกเว้นและรหัสข้อยกเว้น
สำคัญ:มันจะล้มเหลวหากข้อยกเว้นที่คาดไว้ไม่เกิดขึ้นเช่นกัน
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()
ไม่ได้มีไว้เพื่อใช้ในแบบที่ฉันไม่คิดอย่างน้อยก็ในปัจจุบัน (PHPUnit 3.6.11); มันทำหน้าที่เป็นข้อยกเว้นตัวเอง โดยใช้ตัวอย่างของคุณถ้า$this->fail("Expected exception not thrown")
จะเรียกว่าแล้วcatch
บล็อกจะถูกเรียกและ$e->getMessage()
เป็น"ที่คาดว่าจะมีข้อยกเว้นไม่โยน"
fail
อาจจะเป็นหลังจากที่จับบล็อกไม่ได้อยู่ในลอง
fail
ไม่ควรอยู่ในtry
บล็อค ในตัวมันเองเรียกcatch
บล็อกที่ให้ผลลัพธ์ที่ผิดพลาด
catch(Exception $e)
ผมเชื่อว่าเหตุผลนี้ไม่ได้ทำงานได้ดีเป็นสถานการณ์บางอย่างที่มันจับข้อยกเว้นทั้งหมดที่มี วิธีนี้ได้ผลค่อนข้างดีสำหรับฉันเมื่อฉันพยายามที่จะจับข้อยกเว้นเฉพาะ:try { throw new MySpecificException; $this->fail('MySpecificException not thrown'); } catch(MySpecificException $e){}
คุณสามารถใช้ส่วนขยาย assertExceptionเพื่อยืนยันข้อยกเว้นมากกว่าหนึ่งข้อระหว่างการทดสอบหนึ่งครั้ง
แทรกวิธีการลงใน TestCase ของคุณและใช้:
public function testSomething()
{
$test = function() {
// some code that has to throw an exception
};
$this->assertException( $test, 'InvalidArgumentException', 100, 'expected message' );
}
ฉันยังสร้างนิสัยให้กับคนรักของรหัสที่ดี ..
assertException
ไม่มีการกำหนดไว้ ฉันไม่พบมันในคู่มือ PHPUnit
asertException
วิธีการไม่ได้เป็นส่วนหนึ่งของ PHPUnit เดิม คุณต้องรับPHPUnit_Framework_TestCase
คลาสและเพิ่มวิธีการเชื่อมโยงในโพสต์ด้านบนด้วยตนเอง กรณีทดสอบของคุณจะสืบทอดคลาสที่สืบทอดนี้
ทางเลือกอื่นสามารถเป็นดังนี้:
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Expected Exception Message');
\PHPUnit_Framework_TestCase
โปรดตรวจสอบว่าขอบเขตระดับการทดสอบของคุณ
expectException
วิธีการPHPUnit ไม่สะดวกมากเนื่องจากช่วยให้สามารถทดสอบข้อยกเว้นเดียวเท่านั้นสำหรับวิธีทดสอบ
ฉันได้ทำฟังก์ชันผู้ช่วยนี้เพื่อยืนยันว่าบางฟังก์ชันมีข้อยกเว้น:
/**
* 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');
}
เพิ่มไปยังคลาสทดสอบของคุณและเรียกวิธีนี้:
public function testSomething() {
$this->assertException(\PDOException::class, function() {
new \PDO('bad:param');
});
$this->assertException(\PDOException::class, function() {
new \PDO('foo:bar');
});
}
" แนวปฏิบัติที่ดีที่สุด " ของ PHPUnit ในปัจจุบันสำหรับการทดสอบข้อยกเว้นดูเหมือนว่า ... น่าเบื่อ ( เอกสาร )
เนื่องจากฉันต้องการมากกว่าexpectException
การนำไปใช้ในปัจจุบันฉันจึงสร้างลักษณะที่จะใช้ในกรณีทดสอบของฉัน มันเป็นรหัส~ 50 บรรทัดเท่านั้น
assert
ไวยากรณ์assertNotThrows
Throwable
ข้อผิดพลาดPHP 7ฉันเผยแพร่AssertThrows
คุณลักษณะไปที่ Github และผู้บรรจุหีบห่อเพื่อให้สามารถติดตั้งกับผู้แต่งได้
เพียงเพื่อแสดงให้เห็นถึงจิตวิญญาณที่อยู่เบื้องหลังไวยากรณ์:
<?php
// Using simple callback
$this->assertThrows(MyException::class, [$obj, 'doSomethingBad']);
// Using anonymous function
$this->assertThrows(MyException::class, function() use ($obj) {
$obj->doSomethingBad();
});
สวยเนี๊ยบ?
โปรดดูตัวอย่างด้านล่างสำหรับการใช้งานที่ครอบคลุมมากขึ้น:
<?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()
คือassertEquals(mixed $expected, mixed $actual...)
ย้อนกลับในตัวอย่างของคุณดังนั้นมันควรจะเป็น$this->assertEquals("Exception message", $ex->getMessage());
นี่คือข้อยกเว้นทั้งหมดที่คุณสามารถทำได้ โปรดทราบว่าทั้งหมดของพวกเขาไม่จำเป็น
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!');
}
}
/**
* @expectedException Exception
* @expectedExceptionMessage Amount has to be bigger then 0!
*/
public function testDepositNegative()
{
$this->account->deposit(-7);
}
ระวังให้มาก"/**"
สังเกตคู่ "*" การเขียนเฉพาะ "**" (เครื่องหมายดอกจัน) จะทำให้รหัสของคุณล้มเหลว ตรวจสอบให้แน่ใจว่าคุณใช้ phpUnit เวอร์ชันล่าสุดด้วย ในรุ่นก่อนหน้าของ phpunit @ ที่ไม่คาดคิดข้อยกเว้นไม่ได้รับการสนับสนุน ฉันมี 4.0 และมันไม่ทำงานสำหรับฉันฉันต้องอัปเดตเป็น 5.5 https://coderwall.com/p/mklvdw/install-phpunit-with-composerเพื่ออัปเดตด้วยผู้แต่ง
สำหรับ PHPUnit 5.7.27 และ PHP 5.6 และเพื่อทดสอบข้อยกเว้นหลายรายการในการทดสอบครั้งเดียวสิ่งสำคัญคือการบังคับให้ทำการทดสอบข้อยกเว้น การใช้การจัดการข้อยกเว้นเพียงอย่างเดียวเพื่อยืนยันอินสแตนซ์ของข้อยกเว้นจะข้ามการทดสอบสถานการณ์หากไม่มีข้อยกเว้นเกิดขึ้น
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>; }
}
นี่คือการทดสอบ
class FunctionTest extends \PHPUnit_Framework_TestCase{
public function testException(){
$this->setExpectedException(<YOUR_EXCEPTION>::class);
yourfunction(1,2);//add vars that cause the exception
}
}
PhpUnit เป็นห้องสมุดที่น่าทึ่ง แต่ประเด็นนี้ค่อนข้างน่าผิดหวัง นี่คือเหตุผลที่เราสามารถใช้ไลบรารี opensource turbotesting-php ซึ่งมีวิธีการยืนยันที่สะดวกมากเพื่อช่วยเราทดสอบข้อยกเว้น พบได้ที่นี่:
และเพื่อใช้งานเราจะทำดังต่อไปนี้:
AssertUtils::throwsException(function(){
// Some code that must throw an exception here
}, '/expected error message/');
หากรหัสที่เราพิมพ์ภายในฟังก์ชั่นที่ไม่ระบุชื่อไม่ได้เกิดข้อยกเว้นข้อยกเว้นจะถูกโยนทิ้ง
หากรหัสที่เราพิมพ์ภายในฟังก์ชั่นที่ไม่ระบุชื่อเกิดข้อยกเว้น แต่ข้อความไม่ตรงกับ regexp ที่คาดไว้จะมีการโยนข้อยกเว้นด้วย