PHPUnit的:嘲笑除了一些所有方法(PHPUnit: mock all methods exce

2019-09-17 20:33发布

我正在写一个PHPUnit的测试中,我需要模拟一些依赖,但我需要一对夫妇的方法仍像以前一样工作。 也就是说,我有:

class Dependency {
// some stuff not important for the test
  public function thisOneINeed() {
   /// complex code
  }
// some more stuff
}

所以我做这样的事情:

// prepare mock object
$dep = $this->getMockBuilder('Dependency')->disableOriginalConstructor()->getMock();
// mock out some other method that should return fixed value
$dep->expects($this->any())->method("shouldGetTrue")->will($this->returnValue(true));
// run test code, it will use thisOneINeed() and shouldGetTrue()
$result = $testSubject->runSomeCode($dep);
$this->assertEquals($expected, $result);

一切是除了法测得的thisOneINeed()被嘲笑了,所以我不明白复杂的代码运行,我需要它为运行runSomeCode()才能正常工作。 在该代码thisOneINeed()不调用任何其他方法,但需要适当的测试,它不返回固定值,所以我不能只是把静态的returnValue()那里。 而据我所知的PHPUnit没有的方法等returnValue()上面写着“呼叫父”。 它有returnCallback()但是也没有办法告诉它,只要我能看到“呼吁父类的这个方法。”

我可以做的所有方法的列表Dependency ,删除thisOneINeed从它并将它传递给setMethods()构建模拟的时候,但我不喜欢这样的做法,看起来缺憾。

我也可以这样做:

class MockDependency extends Dependency
{
    // do not let the mock kill thisOneINeed function
    final public function thisOneINeed()
    {
        return parent::thisOneINeed();
    }
}

然后用MockDependency打造的模拟对象,而这个工作过,但我不喜欢做手工模拟。

那么,有没有更好的办法来做到这一点?

Answer 1:

我认为,如果你想使用PHPUnit的模拟生成器,然后创建的所有方法的数组,除去一个你需要的,并将它传递给setMethods是你需要做什么。

我个人认为应该在很多情况下,有ReflectionClass的子类,我可以添加方法,当我需要他们。

class MyReflectionClass extends ReflectionClass
{
    public function getAllMethodNamesExcept(array $excluded)
    {
        $methods = array_diff(
            get_class_methods($this->name), 
            $excluded
        );
        return $methods;
    }
}

你也可以使用不同的嘲弄框架,支持你想要做什么。 例如, Phake具有thenCallParent方法。 我已经使用Phake最近因为我需要能够捕获被传递给方法的参数启动。 这是证据充分的,值得一试。



文章来源: PHPUnit: mock all methods except some