模拟构建器不替换方法签名

时间:2017-03-01 21:01:12

标签: php phpunit

模拟是不是应该替换方法及其参数?

我不明白这是如何工作的,我复制粘贴示例,但是我在每个应该开箱即用的示例上遇到麻烦。

我遇到的问题是方法没有删除它们的参数,所以如果一个方法有一定的依赖作为参数,我也必须将它传递给mock的方法..

手册甚至说默认情况下所有方法都被返回null的空方法替换。

我正在使用5.7(php 5.6)

class SomeClass
{
    public function doSomething(\Exception $e)
    {
        // Do something.
    }
}

class StubTest extends TestCase
{
    public function manualExampleDoesntWork()
    {
        // Create a stub for the SomeClass class.
        $stub = $this->createMock(SomeClass::class);

        // Configure the stub.
        $stub->method('doSomething')
             ->willReturn('foo');

        // Calling $stub->doSomething() will now return
        // 'foo'.
        $this->assertEquals('foo', $stub->doSomething());
    }

    public function ...
    {
        // Should be enough, doesnt work
        $stub = $this->createMock(SomeClass::class);
        $stub->doSomething(); // error

        // Neither
        $stub = $this->createMock(SomeClass::class);
        $stub->method('doSomething')
             ->withAnyParameters()
             ->willReturn('foo');
        $stub->doSomething(); // error

        // Same for manually building with the mockbuilder..
    }
}

结果:Argument 1 passed to Mock_***95::doSomething() must be an instance of Exception, none given

这只是一个例子,我已经尝试了创建模拟的所有可能的变体,所有这些都导致我无法替换参数..

1 个答案:

答案 0 :(得分:1)

关于方法重载/覆盖。 PHP不像C ++或Java那样支持这种东西 - 这意味着你不能在当前类的范围内或在继承链中声明具有相同名称和不同参数列表的方法。方法签名必须保持不变。一个例外是__construct,它可以用不同的签名覆盖。还应该提到PHP确实有重载概念,但它有点不同的想法。您可以阅读更多herehere

关于您的特定示例,上述所有内容均表示您必须使用doSomething类的实例或Exception的存根调用Exception,因为doSomething方法属于SomeClass {1}}存根仍然具有与真实SomeClass相同的签名。另一种选择可能是将其声明为public function doSomething(\Exception $e = NULL)

默认情况下,doSomething mock中SomeClass方法的实现是空的 - 直到你配置它为止。