8

我正在测试setSubject将主题设置为(空主题)的方法,如果它丢失。如果试图访问未声明的属性,Zend_Mail 会抛出异常(例如,缺少电子邮件主题,最好抛出一些异常)。更多信息: http: //framework.zend.com/issues/browse/ZF-11371 这是我需要使用才能成功测试它:

班级

protected function setSubject()
{
    # catch exception thrown if non existing $this->message object property is accessed
    try
    {
      $this->subject = $this->defunctTheContent($this->message->getHeaders(), $this->message->subject);
    }
    catch (Zend_Mail_Exception $e)
    {
    }
    if( ! $this->subject)
      $this->subject = '(empty subject)';
}

测试

public function testNoSubject()
{
  $email = new parseEmail(file_get_contents('mail.x'));
  $this->AssertEquals('(empty subject)', $email->subject);
}

但是,如果我尝试此代码,您会看到 catch 块是空的...

protected function setSubject()
{
    try
    {
      $this->subject = $this->defunctTheContent($this->message->getHeaders(), $this->message->subject);
    }
    catch (Zend_Mail_Exception $e)
    {
      $this->subject = '(empty subject)';
    }
}

测试失败并显示消息:

有 1 个错误:

1) Email_ParseTest::testNoSubject InvalidArgumentException: 主题是必需的

它抱怨 $this->subject 未设置(或类似)。

更多信息:

  • PHP 5.4.8
  • Zend 框架 1.9.5
  • PHPUnit 3.6.12
  • subject被定义为空字符串 ( "")

我已经“手动”测试了第二种方法,它按预期工作(主题设置在 catch 块中)。我对 PHPUnit 没有太多经验,所以这可能很E_PEBKAC容易。

4

2 回答 2

3

除非我误解了您的问题,否则您正在尝试测试受保护的方法……您不能这样做。假设通过测试使用它们的公共方法来测试受保护和私有方法。

如果您将 PHP 5.3.2+ 与 PHPUnit 一起使用,您可以在运行测试之前通过使用反射将它们设置为公开来直接测试您的私有和受保护方法,但是,正如我所提到的,您应该测试公共方法。

但是如果你想使用反射,这里有一个通用的例子:

protected static function getMethod($name) {
  $class = new ReflectionClass('MyClass');
  $method = $class->getMethod($name);
  $method->setAccessible(true);
  return $method;
}

public function testFoo() {
  $foo = self::getMethod('foo');
  $obj = new MyClass();
  $foo->invokeArgs($obj, array(...));
  ...
}
于 2012-12-22T16:07:59.500 回答
1

看起来你捕捉到了错误的异常: Zend_Mail 似乎抛出了一个InvalidArgumentException,而你捕捉到了一个Zend_Mail_Exception.

试试下面的代码:

protected function setSubject()
{
    # catch exception thrown if non existing $this->message object property is accessed
    try {
        $this->subject = $this->defunctTheContent($this->message->getHeaders(), $this->message->subject);
    }
    catch (InvalidArgumentException $e) {
        $this->subject = '(empty subject)';
    }
}

编辑

再次阅读您的问题,我会说这Zend_Mail_Exception永远不会被抛出。如果您从第一个代码块中删除try/ catch,我敢打赌它也会起作用:

protected function setSubject()
{
    $this->subject = $this->defunctTheContent($this->message->getHeaders(), $this->message->subject);
    if (! $this->subject) {
        $this->subject = '(empty subject)';
    }
}

第 396 行引用了一个不存在的标头,但看起来即使$this->subject为空也不会触发它(异常类和消息与您的测试结果不匹配)。我怀疑这个头文件之前已经在 Zend 或其他地方设置为空值。

这可以解释为什么在第二种情况下,$this->subject永远不会设置(catch代码永远不会执行)。可能是由检测到未设置的类InvalidArgumentException抛出的。parseEmailsubject

然而,第二个块确实无条件地检查! $this->subject,并相应地设置它。所以测试通过了。

总结一下:

  • Zend_Mail_Exception永远不会被抛出
  • InvalidArgumentException被扔进去parseEmail
于 2012-12-04T11:22:42.733 回答