在Codeception Functional Cept中设置预期的异常

时间:2014-07-27 19:43:31

标签: php laravel laravel-4 phpunit codeception

我想做类似的事情:

$I->setExpectedException('Laracasts\Validation\FormValidationException');

在一个功能性的cept中。有机会这样做吗?

\PHPUnit_Framework_TestCase::setExpectedException('Laracasts\Validation\FormValidationException');

上面的代码将单独工作,但是如果我运行codecept run,那么一旦预期异常的测试完成,测试就会卡住。

这是我的设置:

YML:

class_name: FunctionalTester
modules:
    enabled: [Filesystem, Db, FunctionalHelper, Laravel4, Asserts]

2 个答案:

答案 0 :(得分:11)

我认为这是一个带有Laravel 4模块的known problem用于编码,不确定它是否会很快修复,但同时我创建了一个辅助函数来测试异常:

在文件 tests / _support / FunctionalHelper.php 中添加以下方法:

public function seeExceptionThrown($exception, $function)
{
    try
    {
        $function();
        return false;
    } catch (Exception $e) {
        if( get_class($e) == $exception ){
            return true;
        }
        return false;
    }
}

您可以在 Cepts 中使用它,如下所示:

$I = new FunctionalTester($scenario);
$I->assertTrue(
    $I->seeExceptionThrown('Laracasts\Validation\FormValidationException', function() use ($I){
    //All actions that you expect to generate the Exception
    $I->amOnPage('/users/edit/1');
    $I->fillField('name', '');
    $I->click('Update');
}));

答案 1 :(得分:1)

我稍微扩展了Mind的解决方案:

public function seeException($callback, $exception = 'Exception', $message = '')
  {
    $function = function () use ($callback, $exception) {
      try {
        $callback();
        return false;
      }
      catch (Exception $e) {
        if (get_class($e) == $exception or get_parent_class($e) == $exception) {
          return true;
        }
        return false;
      }
    };
    $this->assertTrue($function(), $message);
  }

在你的知识中你可以

$I->seeException('Laracasts\Validation\FormValidationException', function() use ($I){
    //All actions that you expect to generate the Exception
    $I->amOnPage('/users/edit/1');
    $I->fillField('name', '');
    $I->click('Update');
})

这样,在异常测试方法之外不需要assertTrue。你也可以省略第二个参数,如果它对你很好,也知道抛出异常。最后,您可以将消息字符串作为第三个参数。这样,如果失败,你可以使错误更具表现力。

修改 请原谅,我错过了一件事。在FunctionalHelper.php中,您必须扩展父项_beforeSuite方法:

public function _beforeSuite()
  {
    parent::_beforeSuite();
    $this->assert = $this->getModule('Asserts');

  }

<强> EDIT2 刚刚发现,如果你隐式断言抛出异常并且php的本机异常不是出现的异常父,则测试方法不起作用,因为该方法只检查第一和第二异常级别。要使方法检查整个预期堆栈,您必须使用此方法

public function assertThrows($callback, $exception = 'Exception', $message = '')
  {
    $function = function () use ($callback, $exception) {
      $getAncestors = function($e) {

        for ($classes[] = $e; $e = get_parent_class ($e); $classes[] = $e);
        return $classes;

      }

      try {
        $callback();
        return false;
      }
      catch (Exception $e) {
        if (get_class($e) == $exception or in_array($e, $getAncestors($e))) {
          return true;
        }
        return false;
      }
    };
    $this->assertTrue($function(), $message);
  }