【问题标题】:How to check the exception thrown correctly by PHPUnit?如何检查 PHPUnit 正确抛出的异常?
【发布时间】:2012-05-13 22:10:05
【问题描述】:

我的 CalTest 类中的 Cal 类中有 div(),有以下方法来测试 div()。

public fucnction div($a,$b){
   if($b == 0){
    throw new Exception("Divided by zero");
   }
   return $a/$b
}

我只能通过 testDiv() 但 testDiv2()。

我想检查一下使用 PHPUnit 正确抛出的异常。我在这里想念什么?非常感谢您的帮助。谢谢!

【问题讨论】:

  • 嗯,看起来你的注释是正确的,实际上(所以可能不是重复的)。您是否尝试过删除注释 @ 和异常名称之间的选项卡?编辑:实际上,我认为问题在于您的 expectedMessage 不是异常消息。
  • @Corbin 我读了那个问题并尝试了它并尝试了不同的例外。但没有结果
  • PHPUnit 会自动捕获异常吗?你不需要做一个 try/catch 块吗?
  • @Anthony 不,你可以像 RJ 一样在评论区做。

标签: php exception phpunit testcase


【解决方案1】:

在 PHPUnit 抛出的异常中是这样说的:

您不能排除通用异常类。

让你的类抛出more detailed Exceptions,并进一步指定你在单元测试中期望的异常类型。

【讨论】:

  • 即使我认为 InvalidArgumentException 它也不起作用。我认为它不是通用异常类,对吧??
  • 你抛出了一个通用异常,不是吗?
  • @vascowhite : 那我该怎么办我应该抛出 InvalidArgumentException 吗?
  • 如果这就是你告诉 PHPUnit 所期望的,那么这就是你应该抛出的逻辑,不是吗?
  • 这是一个糟糕的建议。让供应商 API 规定如何设计代码是一种不好的做法。 IMO PHPUnit 在这个上丢了球。我们中的一些人选择异常代码而不是抛出自定义异常。
【解决方案2】:

您的第二张截图(有错误的那张)有

“@expectedException异常”

第三个有

@expectedException InvalidArgumentException

你真的仍然得到错误吗?你保存文件了吗?


为我工作:

Foo.php

<?php

class Foo
{
    static function t()
    {
        throw new InvalidArgumentException('Hi there');
    }
}

?>

FooTest.php

<?php
require_once 'Foo.php';
class FooTest extends PHPUnit_Framework_TestCase
{
    /**
     * @expectedException InvalidArgumentException
     */
    public function testT()
    {
        Foo::t();
    }
}

?>

结果

$ phpunit .
PHPUnit 3.6.10 by Sebastian Bergmann.

.

Time: 0 seconds, Memory: 5.25Mb

OK (1 test, 1 assertion)

【讨论】:

  • 是的,没错。那是因为我在拍摄屏幕截图时尝试了两种方式(两者都不起作用)。对此感到抱歉。
  • 您的功能运行良好。但就我而言,它仍然说 invalidAargumetExepetion
  • 那么请发布最小的代码来重现您的问题。我确定问题出在你这边。
  • 是的,问题在我这边。只有 testDiv2() 困扰着我而不是另一个,所以我想这是我的问题的最小代码。
  • 不,我的意思是我可以复制和粘贴以在我的机器上重现您的问题的代码。
【解决方案3】:

你可以这样做

编写单元测试,然后注入触发异常所需的值

//断言 $this->assertTrue($this->setExpectedException('PHPUnit_Framework_ExpectationFailedException'));

【讨论】:

  • 我不清楚你所说的,你是在告诉我们将此代码插入 testDiv() 或其他什么吗?我在你长高后试过了,但还是一样:'(
  • 我不明白你的评论,但我建议使用 phpunit 资源。 phpunit.de/manual/3.2/en/…
【解决方案4】:

刚刚遇到同样的问题。出于某种原因,PHPUnit 不允许您将 expectedException 设置为通用异常,我不知道为什么。就我个人而言,我选择抛出自定义异常代码,而不是每次我想区分异常时都必须创建一个新的异常类。

我是这样解决的:

/**
 * @expectedException Test_Exception
 */
public function testDivByZero()
{
    try {
        // Fyi you don't need to do an assert test here, as we are only testing the exception, so just make the call
        $result = $this->object->div(1,0);
    } catch (Exception $e) {
        if ('Exception' === get_class($e)) {
            throw new Test_Exception($e->getMessage(), $e->getCode());
        }
    }
 }

 // Test_Exception.php
 class Test_Exception extends Exception
 {
     public function __construct($message = null, $code = 0, Exception $previous = null)
     {
         parent::__construct($message, $code, $previous);
     }
 }

这将允许您以您想要的方式设计您的代码,并抛出“通用”异常。基本上它只是测试 Exception 类,如果它是通用的,则将其重新包装为不同的异常;测试异常。

-- 更新--

昨天发现他们在当前的“master”分支中有removed the generic exception restriction,它将是 3.7。显然,首席工程师不想修补 3.6。

【讨论】:

    【解决方案5】:

    这个问题已经在PHPUnit 3.7.x修复

    您可以在 PHPUnit 3.7.x 中使用以下通用异常

        /**
         * @expectedException Exception     
         */
    

    【讨论】:

      【解决方案6】:

      我创建了一个父类方法来做到这一点。事实上,这个类来自 laravel,但在任何情况下都有效。

      这个方法最酷的部分是在 PHP 中使用匿名函数

      <?php
      class TestCase 
               /* if you are not using laravel, you dont need this 
              extends Illuminate\Foundation\Testing\TestCase */ {
      
          protected function assertThrows( $function , $classException = "/Exception" )
          {
              try 
              {
                  // Anonymous functions FTW
                  $function();
              }
              catch( /Exception $objException )
              {
                  // the assertInstanceOf should solve from here but
                  // it is not working that great
                  // @see http://stackoverflow.com/questions/16833923/phpunit-assertinstanceof-not-working
                  if( $objException instanceof $classException ) {
                      return $this->assertTrue( true );
                  } else {
                      // this will throw a error with a cool message
                      return $this->assertEquals( $classException  , get_class( $objException ));
                  }
              }
              // no exception happened.
              return $this->fail( "Exception " . $classException . " expected." );
          }
      
      }
      
      class LanguageTest extends TestCase {
      
          /**
           * Test the translation
           *
           * @return void
           */
          public function testTranslation()
          {
              // this test may be ok
              $this->assertThrows( 
                  function(){ throw new Full\Path\Exception(":("); }, 
                  "Full\Path\Exception" );
      
              // this test may fail 
              $this->assertThrows( 
                  function(){ return 1 + 1; }, 
                  "Some\Excepted\Exception" );
      
              // this test may work 
              $this->assertThrows( 
                  function(){ throw new Exception( "sad" ); }
              );
          }
      
      } 
      

      【讨论】:

        猜你喜欢
        • 2020-06-14
        • 1970-01-01
        • 1970-01-01
        • 2011-08-06
        • 1970-01-01
        • 2015-05-07
        • 1970-01-01
        • 1970-01-01
        • 2016-07-21
        相关资源
        最近更新 更多