PHPUnit 断言没有调用任何方法

Posted

技术标签:

【中文标题】PHPUnit 断言没有调用任何方法【英文标题】:PHPUnit assert no method is called 【发布时间】:2013-09-15 16:54:31 【问题描述】:

我有一个使用 ServiceB 的 ClassA。在某种情况下,ClassA 最终应该不会调用 ServiceB 的任何方法。我现在想测试一下,确实没有调用任何方法。

这可以按如下方式完成:

$classA->expects( $this->never() )->method( 'first_method' );
$classA->expects( $this->never() )->method( 'second_method' );
...

有没有办法简单地声明“不应该在这个对象上调用任何方法”,而不是必须为每个方法指定一个限制?

【问题讨论】:

【参考方案1】:

您还可以模拟一个方法和一个数据提供者,并确保它永远不会被调用。不做任何断言,因为它没有被调用,所以它已经通过了测试。

<?php
    /**
     * @dataProvider dataProvider
     */
    public function checkSomethingIsDisabled( $message, $config, $expected)
    
        $debugMock = $this->getMockBuilder('APP_Class_Name')
            ->disableOriginalConstructor()
            ->setMethods(array('_helper'))
            ->getMock();

        $debugMock = $this->getPublicClass($debugMock);
        $debugMock->_config = $config;
        $viewContent = new stdClass;
        $debugMock->_functionToTest($viewContent);
    

    public function dataProvider()
    
        return [
                'dataset'=>
                    [
                        'message' => 'Debug Disabled',
                        'config' => (object) array(
                            'values' => (object) array(
                                'valueThatWhenFalseDoesntExecuteFunc'=> false
                            )
                        ),
                        // in a probably needed complimentary "imaginary" test we probably  
                        // will have the valueThatWhenFalseDoesntExecuteFunc set to true and on
                        // expected more information to handle and test.
                        'expected' => null
                    ]
                ];
    

【讨论】:

【参考方案2】:

您可以使用方法MockBuilder::disableAutoReturnValueGeneration

例如,在您的测试中覆盖默认TestCase::getMockBuilder

    /**
     * @param string $className
     * @return MockBuilder
     */
    public function getMockBuilder($className): MockBuilder
    
        // this is to make sure, that not-mocked method will not be called
        return parent::getMockBuilder($className)
            ->disableAutoReturnValueGeneration();
    

优点:

除了模拟方法之外,您的所有模拟都不会调用任何东西。无需将-&gt;expects(self::never())-&gt;method(self::anything()) 绑定到所有这些 您仍然可以设置新的模拟。在-&gt;expects(self::never())-&gt;method(self::anything()) 之后你不能

适用于 PhpUnit v7.5.4(可能还有更高版本)。

【讨论】:

【参考方案3】:

是的,很简单,试试这个:

$classA->expects($this->never())->method($this->anything());

【讨论】:

以上是关于PHPUnit 断言没有调用任何方法的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Codeception 功能测试中使用 PHPUnit 断言方法?

PHPUnit:断言两个数组相等,但元素的顺序并不重要

如何使用 PHPUnit 在类中测试单个 void 方法?

PHPUnit 问题断言模拟是使用 Laravel 的 ReflectionProperty 对象

PHPUnit:assertThat()是否增加断言计数?

PHPUnit 断言抛出异常?