有没有办法在使用PHPUnit模拟对象时缩短异常堆栈跟踪?

时间:2015-11-02 14:54:40

标签: php unit-testing exception phpunit

我有大约500个单元测试,总共有大约2000个断言。我还测试了一个方法,其中有一个异常处理,它会影响返回值。

我正在以下列方式创建模拟:

$mockedClass = $this
    ->getMockBuilder('\My\Class\To\Mock')
    ->disableOriginalConstructor()
    ->setMethods(['ThisMethodThrows'])
    ->getMock();

$mockedClass
    ->expects($this->any())
    ->method('ThisMethodThrows')
    ->will($this->throwException(new \Exception));

这很有效。我将此$mockedClass传递给我正在测试其行为的对象,在此方法中,我记录了哪些方法失败以及参数是什么(使用print_r($parameter, true))。

当我单独运行此测试时,它可以工作,但如果我运行整个(500)测试包,当我进行此测试时,print_r会失败,因为它不再能够打印$mockedClass的内容,因为堆栈跟踪由于某种原因,实际上很长,如果我print_r模拟对象进入控制台,该列表基本上是永远的。

这是默认的PHPUnit行为吗?如果没有,我是如何定义应该抛出异常的mock的?如果模拟类的代码是正确的,那么在抛出异常时我能以某种方式缩短输出吗?

1 个答案:

答案 0 :(得分:2)

当您对它们执行print_r时,PHPUnit的模拟对象非常大。所以是的,这将是默认行为。

要缩短输出,请不要使用print_r。您在此测试中看到的问题表明您的代码存在问题。您可能有一个类似的对象,它会对您的生产日志产生大量输出。为什么需要记录整个对象?当/如果您必须通过日志查找出错的内容时,您不希望必须滚动查看对象数据的行和行以查找所需内容。或者,如果错误与之无关,则必须滚动浏览print_r生成的文本墙。这应该可以解决您对断言的问题,并使您的日志更有用。

<强> 更新 由于测试本身运行良好,您可以尝试在自己的进程中运行测试,看看是否可以处理它。将@runInSeparateProcess注释添加到测试中。这可以减少模拟对象的转储大小。

https://phpunit.de/manual/3.7/en/appendixes.annotations.html#appendixes.annotations.runInSeparateProcess

<强> 此外: 你需要小心你的模拟抛出基础异常。当测试失败并且您的代码可以捕获它们时,PHPUnit会抛出自己的异常。这可能会导致您的测试失败,甚至更糟。您应该使用自己的基本例外扩展\Exception类。