PHPUnit:模拟除某些方法外的所有方法 [英] PHPUnit: mock all methods except some

查看:66
本文介绍了PHPUnit:模拟除某些方法外的所有方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个PHPUnit测试,在那里我需要模拟一些依赖关系,但是我需要一些方法,因为它仍然可以像以前一样工作.即,我有:

I'm writing a PHPUnit test, where I need to mock some dependency, but I need a couple of methods for it still work as before. I.e., I have:

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

所以我正在做这样的事情:

So I was doing something like this:

// 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()中的代码不会调用任何其他方法,但是正确的测试是必需的,并且它不会返回固定值,因此我不能仅将static returnValue()放在那里.而且AFAIK PHPunit没有像returnValue()这样的方法,它说"call parent".它具有returnCallback(),但是据我所知没有办法告诉它为父类调用此方法".

And everything is fine except method thisOneINeed() is mocked out so I don't get the complex code to run and I need it to run for runSomeCode() to work properly. That code in thisOneINeed() doesn't call any other methods, but it is needed for the proper test and it doesn't return fixed value, so I can't just put static returnValue() there. And AFAIK PHPunit does not have a method like returnValue() that says "call parent". It has returnCallback() but there's no way to tell it "call this method for parent class" as far as I could see.

我可以列出Dependency中所有方法的列表,从中删除thisOneINeed并将其传递给setMethods(),以构建模拟程序,但是我不喜欢这种方法,看起来很笨拙.

I could make the list of all methods in Dependency, remove thisOneINeed from it and pass it to setMethods() when constructing the mock, but I don't like that approach, looks kludgy.

我也可以这样做:

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

然后使用MockDependency来构建模拟对象,这也可以工作,但是我不喜欢必须手动进行模拟.

and then use MockDependency to build the mock object, and this works too, but I don't like having to do the mock manually.

那么有没有更好的方法可以做到这一点?

So is there a better way to do this?

推荐答案

我认为,如果您要使用PHPUnit的模拟生成器,则创建所有方法的数组,删除所需的方法,然后将其传递给setMethods正是您需要做.

I think if you want to use PHPUnit's mock builder, then creating an array of all methods, removing the one you need, and passing it to setMethods is exactly what you'll need to do.

我个人发现,在很多情况下,拥有ReflectionClass的子类非常有用,可以在需要时向其添加方法.

I've personally found it useful in a lot of cases to have a subclass of ReflectionClass that I can add methods to when I need them.

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

您还可以使用支持您要执行的操作的其他模拟框架.例如, Phake 具有

You could also use a different mocking framework that supports what you want to do. For example, Phake has a thenCallParent method. I've started using Phake recently because I needed to be able to capture the parameters that were passed to a method. It is well-documented and worth a try.

这篇关于PHPUnit:模拟除某些方法外的所有方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆