পিএইচপিউইনিট দাবি করে যে একটি ব্যতিক্রম ছুঁড়েছিল?


337

কেউ কি জানেন যে এমন একটি assertবা এর মতো কিছু আছে যা পরীক্ষা করতে পারে যে কোডটিতে একটি ব্যতিক্রম পরীক্ষা করা হচ্ছে কিনা?


2
এই উত্তরের জন্য: একটি পরীক্ষামূলক কার্যক্রমে মাল্টি-অ্যাসেসরেন্সগুলির কী, এবং আমি কেবল একটি নিক্ষেপ ব্যতিক্রম আশা করব? আমি কি তাদের পৃথক করে একটি পৃথক পরীক্ষার জন্য রেখেছি?
পানওয়ান ওয়াং

উত্তর:


549
<?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);
    }
}

প্রত্যাশিত এক্সেকসেপশন () পিএইচপিউইনিট ডকুমেন্টেশন

পিএইচপিউইনাইট লেখক নিবন্ধটি ব্যতিক্রমগুলির সেরা অভ্যাসগুলির পরীক্ষা করার বিষয়ে বিশদ ব্যাখ্যা সরবরাহ করে।


7
আপনি যদি নেমস্পেস ব্যবহার করেন তবে ভাল আপনাকে পুরো নামস্থান লিখতে হবে:$this->setExpectedException('\My\Name\Space\MyCustomException');
অ্যালক্যালেন

15
আপনি যে কোডটি নিক্ষেপ করবেন বলে আশা করা হচ্ছে তার সঠিক লাইনটি নির্দিষ্ট করতে পারবেন না এটি একটি ত্রুটি আইএমও। এবং একই পরীক্ষায় একাধিক ব্যতিক্রমের জন্য পরীক্ষার অক্ষমতা, অনেক প্রত্যাশিত ব্যতিক্রমের জন্য পরীক্ষাকে সত্যই এক জটিল সমস্যা করে তোলে makes আমি এই সমস্যাগুলি সমাধান করার চেষ্টা করার জন্য একটি আসল দাবি লিখেছিলাম ।
mindplay.dk

18
এফওয়াইআই: ফুপুনিট 5.2.0 setExpectedException পদ্ধতি অবহিত করা হয়, expectExceptionএকের সাথে প্রতিস্থাপন করা হয় । :)
হিজদাভ

41
দস্তাবেজগুলিতে বা এখানে কী উল্লেখ নেই, তবে কোডটি ব্যতিক্রম প্রত্যাখ্যান করে বলে তার পরে কল করা দরকার expectException() । যদিও এটি কারওর কাছে সুস্পষ্ট হতে পারে, তবে এটি আমার জন্য গোটচা ছিল ।
জেসন ম্যাকক্রিরি

7
এটি ডক থেকে সুস্পষ্ট নয়, তবে আপনার ফাংশনের পরে কোনও কোড যা ব্যতিক্রম ছুঁড়েছে তা কার্যকর করা হবে না। সুতরাং আপনি যদি একই পরীক্ষার ক্ষেত্রে একাধিক ব্যতিক্রম পরীক্ষা করতে চান তবে আপনি পারবেন না।
লরেন্ট

122

PHPUnit 9 প্রকাশ না হওয়া পর্যন্ত আপনি একটি ডকব্লক টিকাও ব্যবহার করতে পারেন :

class ExceptionTest extends PHPUnit_Framework_TestCase
{
    /**
     * @expectedException InvalidArgumentException
     */
    public function testException()
    {
        ...
    }
}

পিএইচপি 5.5+ (বিশেষত নেমস্পিড কোড সহ) এর জন্য, আমি এখন ব্যবহার পছন্দ করি ::class


3
আইএমও, এটি পছন্দের পদ্ধতি।
মাইক পার্সেল

12
@ লেভিমরিসন - আইএমএইচও ব্যতিক্রম বার্তাটি পরীক্ষা করা উচিত নয়, একইভাবে লগ বার্তাগুলির জন্য। ম্যানুয়াল ফরেনসিক সম্পাদন করার সময় উভয়ই বহিরাগত, সহায়ক তথ্য হিসাবে বিবেচিত হয় । পরীক্ষার মূল পয়েন্টটি ব্যতিক্রমের ধরণ । এর বাইরে যে কোনও কিছুই বাস্তবায়নের জন্য খুব দৃ .়ভাবে আবদ্ধ। IncorrectPasswordExceptionযথেষ্ট হওয়া উচিত - যে বার্তাটি সমান "Wrong password for bob@me.com"। আপনি যতটা সম্ভব পরীক্ষার লেখার জন্য অল্প সময় ব্যয় করতে চান তা যুক্ত করুন এবং আপনি কীভাবে গুরুত্বপূর্ণ সাধারণ পরীক্ষাগুলি হয়ে ওঠেন তা দেখতে শুরু করে।
ডেভিড হার্কনেস

5
@ ডেভিড হারকনেস আমি অনুভব করেছি যে কেউ এটি নিয়ে আসবে। একইভাবে আমি সম্মত হব যে সাধারণভাবে বার্তাগুলি পরীক্ষা করা খুব কঠোর এবং শক্ত। তবে এটি যে কষাকষি এবং আঁট বাঁধাই যে পারে (উদ্দেশ্যপূর্ণ জোর) হতে কি এই ধরনের একটি বৈশিষ্ট বলবত্ কিছু পরিস্থিতিতে চেয়েছিলেন হয়।
লেবি মরিসন

1
এটি কী প্রত্যাশা করেছিল তা বুঝতে আমি কোনও ডক-ব্লকে দেখব না, তবে আমি আসল পরীক্ষার কোডটি (পরীক্ষার ধরণের নির্বিশেষে) দেখব। অন্যান্য সমস্ত পরীক্ষার জন্য এটি স্ট্যান্ডার্ড; আমি এই কনভেনশনের ব্যতিক্রম (ওহ godশ্বর) ব্যতিক্রম হওয়ার বৈধ কারণগুলি দেখতে পাচ্ছি না ।
কামাফেদার

3
"বার্তাটি পরীক্ষা করবেন না" নিয়মটি বৈধ বলে মনে হচ্ছে, যদি না আপনি কোনও পদ্ধতির পরীক্ষা করেন যা কোডের একাধিক অংশে একই ব্যতিক্রম প্রকারটি ছুঁড়ে দেয়, তবে কেবলমাত্র ত্রুটি আইডি, যা বার্তায় পাস হয় is আপনার সিস্টেমটি ব্যতিক্রম বার্তার উপর ভিত্তি করে ব্যবহারকারীর কাছে একটি বার্তা প্রদর্শন করতে পারে (ব্যতিক্রমের ধরণ নয়)। সেক্ষেত্রে ব্যবহারকারী কোনও বার্তা দেখেন তা বিবেচনা করে না, সুতরাং আপনার ত্রুটি বার্তাটি পরীক্ষা করা উচিত।
ভানজা ডি

34

আপনি যদি পিএইচপি 5.5+ এ চলমান থাকেন তবে আপনি / এর সাথে শ্রেণীর নাম জানতে ::classরেজোলিউশনটি ব্যবহার করতে পারেন । এটি বিভিন্ন সুবিধা সরবরাহ করে:expectExceptionsetExpectedException

  • নামটি তার নেমস্পেসের সাথে পুরোপুরি যোগ্যতা অর্জন করবে (যদি থাকে)।
  • এটি সমাধান করে stringযাতে এটি পিএইচপিউইনাইটের যে কোনও সংস্করণে কাজ করবে।
  • আপনি আপনার আইডিইতে কোড-সমাপ্তি পাবেন।
  • আপনি শ্রেণীর নামটি ভুল টাইপ করলে পিএইচপি সংকলক একটি ত্রুটি নির্গত করে।

উদাহরণ:

namespace \My\Cool\Package;

class AuthTest extends \PHPUnit_Framework_TestCase
{
    public function testLoginFailsForWrongPassword()
    {
        $this->expectException(WrongPasswordException::class);
        Auth::login('Bob', 'wrong');
    }
}

পিএইচপি সংকলন

WrongPasswordException::class

মধ্যে

"\My\Cool\Package\WrongPasswordException"

পিএইচপিউইনিটকে বুদ্ধিমান না করে।

নোট : PHPUnit 5.2 চালু expectException জন্য একটি প্রতিস্থাপন হিসাবে setExpectedException


32

নীচের কোডটি ব্যতিক্রম বার্তা এবং ব্যতিক্রম কোড পরীক্ষা করবে।

গুরুত্বপূর্ণ: প্রত্যাশিত ব্যতিক্রম খুব বেশি ছুঁড়ে না দেওয়া হলে এটি ব্যর্থ হবে।

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());
}

6
$this->fail()কমপক্ষে বর্তমানে নয় (পিএইচপিউনিট ৩.6.১১); আমি মনে করি না এইভাবে ব্যবহার করার উদ্দেশ্যে নয়; এটি নিজেই ব্যতিক্রম হিসাবে কাজ করে। আপনার উদাহরণ ব্যবহার করে, যদি $this->fail("Expected exception not thrown")বলা হয়, তারপর catchব্লক সূত্রপাত হয় এবং $e->getMessage()হয় "ব্যতিক্রম নিক্ষিপ্ত প্রত্যাশিত"
কেন

1
@ সম্ভবত আপনি ঠিক বলেছেন কলটি failসম্ভবত ধরা দেওয়ার পরে , চেষ্টা করার অভ্যন্তরে নয়।
ফ্রাঙ্ক ফার্মার

1
আমাকে ডাউনটাতে হবে কারণ কলটি ব্লকে failথাকা উচিত নয় try। এটি নিজেই catchমিথ্যা ফলাফল তৈরি করে trig
টোয়েন্টি

6
আমি বিশ্বাস করি এটি কার্যকরভাবে কাজ না করার কারণটি কিছু পরিস্থিতি হ'ল এটি সমস্ত ব্যাতিক্রমকে ধরে ফেলছে catch(Exception $e)। আমি যখন নির্দিষ্ট ব্যতিক্রমগুলি ধরার চেষ্টা করি তখন এই পদ্ধতিটি আমার পক্ষে বেশ ভাল কাজ করে:try { throw new MySpecificException; $this->fail('MySpecificException not thrown'); } catch(MySpecificException $e){}
স্পাইলে

23

আপনি একটি পরীক্ষার প্রয়োগের সময় একাধিক ব্যতিক্রম দৃ as় করতে assertException এক্সটেনশন ব্যবহার করতে পারেন ।

আপনার টেস্টকেসে পদ্ধতি সন্নিবেশ করুন এবং ব্যবহার করুন:

public function testSomething()
{
    $test = function() {
        // some code that has to throw an exception
    };
    $this->assertException( $test, 'InvalidArgumentException', 100, 'expected message' );
}

আমি সুন্দর কোড প্রেমীদের জন্যও একটি বৈশিষ্ট্য তৈরি করেছি ..


আপনি কোন PHPUnit ব্যবহার করছেন? আমি PHPUnit 4.7.5 ব্যবহার করছি, এবং সেখানে assertExceptionসংজ্ঞায়িত হয়নি। আমি পিএইচপিউইনিট ম্যানুয়ালটিতে এটিও খুঁজে পাচ্ছি না।
ফিজিক্যাল্যাট্রাকশন

2
asertExceptionপদ্ধতি মূল PHPUnit অংশ নয়। আপনাকে অবশ্যই PHPUnit_Framework_TestCaseশ্রেণীর উত্তরাধিকারী হতে হবে এবং উপরের পোস্টে ম্যানুয়ালি লিঙ্কিত পদ্ধতি যুক্ত করতে হবে । আপনার পরীক্ষার কেসগুলি এই উত্তরাধিকারসূত্রে প্রাপ্ত শ্রেণীর উত্তরাধিকারী হবে।
হিজদাভ

18

বিকল্প উপায় নিম্নলিখিত হতে পারে:

$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Expected Exception Message');

আপনার পরীক্ষা ক্লাস প্রসারিত নিশ্চিত করুন \PHPUnit_Framework_TestCase


নিশ্চিতভাবে এই সিনট্যাক্সের সর্বাধিক চিনি
অ্যান্ড্রুএমসিএলাগান

13

পিএইচপিউনিট expectExceptionপদ্ধতিটি খুব অসুবিধে হয় কারণ এটি পরীক্ষার পদ্ধতিতে কেবল একটি ব্যতিক্রম পরীক্ষা করতে দেয়।

আমি এই সহায়কটির কার্যকারিতাটি দৃsert়তার জন্য করেছি যে কোনও ফাংশন ব্যতিক্রম ছুঁড়ে ফেলেছে:

/**
 * 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');
    });
}

অবশ্যই উত্তরগুলির মধ্যে সর্বোত্তম সমাধান! এটিকে একটি বৈশিষ্ট্যে ফেলে দিন এবং এটি প্যাকেজ করুন!
ডোমডামব্রোগিয়া

11

বিস্তৃত সমাধান

ব্যতিক্রম পরীক্ষার জন্য পিএইচপিউইনটির বর্তমান " সেরা অনুশীলন " মনে হচ্ছে .. অভাবনীয় ( ডক্স )।

যেহেতু আমি বর্তমান প্রয়োগের চেয়ে বেশি চেয়েছিexpectException , তাই আমি আমার পরীক্ষার কেসগুলিতে ব্যবহার করার জন্য একটি বৈশিষ্ট্য তৈরি করেছি। এটি কোডের কেবল 50 ডলার

  • পরীক্ষায় একাধিক ব্যতিক্রম সমর্থন করে
  • ব্যতিক্রম নিক্ষেপ করার পরে আহ্বান করা সমর্থনগুলি সমর্থন করে
  • দৃ Rob় এবং পরিষ্কার ব্যবহারের উদাহরণ
  • স্ট্যান্ডার্ড assertসিনট্যাক্স
  • কেবল বার্তা, কোড এবং ক্লাসের চেয়ে বেশি জন্য দৃser় সমর্থন করে
  • বিপরীত দৃser় সমর্থন, assertNotThrows
  • পিএইচপি 7 Throwableত্রুটি সমর্থন করে

গ্রন্থাগার

আমি গিথুবAssertThrows এবং প্যাক্যাগিস্টে বৈশিষ্ট্যটি প্রকাশ করেছি যাতে এটি সুরকারের সাথে ইনস্টল করা যায়।

সাধারণ উদাহরণ

কেবল সিনট্যাক্সের পেছনের চেতনাটি বর্ণনা করার জন্য:

<?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();
        });
    }
}

?>

4
সামান্য পরিহাস যে আপনার প্যাকেজ ইউনিট পরীক্ষার জন্য ইউনিট পরীক্ষার অন্তর্ভুক্ত না।
ডোমডামব্রোগিয়া

2
@ জ্যাম- বেগুইনকে ধন্যবাদ @ ডিডামব্রোগিয়া এটির এখন ইউনিট পরীক্ষা রয়েছে।
jchook

8
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());
রজার ক্যাম্পেনের

7

আপনি করতে পারেন এমন সমস্ত ব্যতিক্রম দৃser়তা এখানে। মনে রাখবেন যে এগুলি সমস্ত alচ্ছিক

class ExceptionTest extends PHPUnit_Framework_TestCase
{
    public function testException()
    {
        // make your exception assertions
        $this->expectException(InvalidArgumentException::class);
        // if you use namespaces:
        // $this->expectException('\Namespace\MyExceptio‌​n');
        $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!');
    }
}

ডকুমেন্টেশন এখানে পাওয়া যাবে


এটি ভুল কারণ পিএইচপি প্রথম নিক্ষিপ্ত ব্যতিক্রম থামিয়েছে। পিএইচপিউনিট পরীক্ষা করে যে নিক্ষিপ্ত ব্যতিক্রমটি সঠিক ধরণের রয়েছে এবং বলে «পরীক্ষাটি ঠিক আছে», এটি দ্বিতীয় ব্যতিক্রম সম্পর্কেও জানে না।
ফাইনাইনস

3
/**
 * @expectedException Exception
 * @expectedExceptionMessage Amount has to be bigger then 0!
 */
public function testDepositNegative()
{
    $this->account->deposit(-7);
}

সম্পর্কে খুব যত্নশীল হন "/**", ডাবল "*" লক্ষ্য করুন। কেবল "**" (অস্টেরিক্স) লেখা আপনার কোডটি ব্যর্থ করবে। আপনার পিএইচপিউনিটের সর্বশেষ সংস্করণ ব্যবহার করা নিশ্চিত করুন। Phpunit এর পূর্ববর্তী কয়েকটি সংস্করণে @ এক্সপেক্টড এক্সসেপশন ব্যতিক্রম সমর্থিত নয়। আমার 4.0 ছিল এবং এটি আমার পক্ষে কার্যকর হয়নি, সুরকারের সাথে আপডেট করার জন্য আমাকে 5.5 https://coderwall.com/p/mklvdw/install-phpunit-with-composer আপডেট করতে হয়েছিল ।


0

পিএইচপিউনিট 5.7.27 এবং পিএইচপি 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());

}

0
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 

   }

}

0

পিএইচপিউনিট একটি আশ্চর্যজনক গ্রন্থাগার, তবে এই নির্দিষ্ট পয়েন্টটি কিছুটা হতাশার। এই কারণেই আমরা টারবোটেস্টিং-পিএইচপি ওপেনসোর্স লাইব্রেরিটি ব্যবহার করতে পারি যা ব্যতিক্রমগুলি পরীক্ষা করতে আমাদের সহায়তা করার জন্য খুব সুবিধাজনক দৃser় পদ্ধতি রয়েছে। এটি এখানে পাওয়া যায়:

https://github.com/edertone/TurboTesting/blob/master/TurboTesting-Php/src/main/php/utils/AssertUtils.php

এবং এটি ব্যবহার করার জন্য, আমরা কেবল নিম্নলিখিতটি করতাম:

AssertUtils::throwsException(function(){

    // Some code that must throw an exception here

}, '/expected error message/');

বেনামে ফাংশনটির ভিতরে আমরা যে কোডটি টাইপ করি তা যদি একটি ব্যতিক্রম না ফেলে তবে একটি ব্যতিক্রম ছুঁড়ে দেওয়া হবে।

বেনামে ফাংশনটির ভিতরে আমরা যে কোডটি টাইপ করি তা যদি একটি ব্যতিক্রম ছুঁড়ে, তবে এর বার্তাটি প্রত্যাশিত রিজেক্সের সাথে মেলে না, একটি ব্যতিক্রমও ছুঁড়ে দেওয়া হবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.