模拟新类对象调用的方法的单元测试 [英] Unit test for mocking a method called by new class object

查看:81
本文介绍了模拟新类对象调用的方法的单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为这样的现有代码编写单元测试

I am writing unit test for an existing code which is like this

class someClass {
    public function __construct() { ... }

    public function someFoo($var) {
        ...
        $var = "something";
        ...
        $model = new someClass();
        model->someOtherFoo($var);
    }

    public someOtherFoo($var){
         // some code which has to be mocked
    }
}

在这里我应该如何模拟对函数"someOtherFoo"的调用,以使其在someOtherFoo内部不执行"some code"?

Here how should I be able to mock the call to function "someOtherFoo" such that it doesn't execute "some code" inside someOtherFoo?

class someClassTest {
   public function someFoo() {
      $fixture = $this->getMock('someClass ', array('someOtherFoo'));
      $var = "something";
      ....
      // How to mock the call to someOtherFoo() here
   }

}

是否可以模拟出构造函数,使其返回我自己的构造函数或变量?

Is it possible to mock out the constructor so that it returns my own constructed function or variable?

谢谢

推荐答案

无论您在测试中的方法中有new XXX(...),还是注定了.将实例提取到同一类的新方法createSomeClass(...)中.这样,您可以为被测类创建部分模拟,该模拟从新方法返回存根或模拟值.

Wherever you have new XXX(...) in a method under test, you are doomed. Extract the instantiation to a new method--createSomeClass(...)--of the same class. This allows you to create a partial mock of the class under test that returns a stubbed or mock value from the new method.

class someClass {
    public function someFoo($var) {
        $model = $this->createSomeClass();  // call method instead of using new
        model->someOtherFoo($var);
    }

    public function createSomeClass() {  // now you can mock this method in the test
        return new someClass();
    }

    public function someOtherFoo($var){
         // some code which has to be mocked
    }
}

在测试中,在调用someFoo()的实例中模拟createSomeClass(),在从第一个模拟调用返回的实例中模拟someOtherFoo().

In the test, mock createSomeClass() in the instance on which you call someFoo(), and mock someOtherFoo() in the instance that you return from the first mocked call.

function testSomeFoo() {
    // mock someOtherFoo() to ensure it gets the correct value for $arg
    $created = $this->getMock('someClass', array('someOtherFoo'));
    $created->expects($this->once())
            ->method('someOtherFoo')
            ->with('foo');

    // mock createSomeClass() to return the mock above
    $creator = $this->getMock('someClass', array('createSomeClass'));
    $creator->expects($this->once())
            ->method('createSomeClass')
            ->will($this->returnValue($created));

    // call someFoo() with the correct $arg
    $creator->someFoo('foo');
}

请记住,由于该实例正在创建同一类的另一个实例,因此通常会涉及两个实例.如果可以使它更清晰,则可以在此处使用相同的模拟实例.

Keep in mind that because the instance is creating another instance of the same class, two instances will normally be involved. You could use the same mock instance here if it makes it clearer.

function testSomeFoo() {
    $fixture = $this->getMock('someClass', array('createSomeClass', 'someOtherFoo'));

    // mock createSomeClass() to return the mock
    $fixture->expects($this->once())
            ->method('createSomeClass')
            ->will($this->returnValue($fixture));

    // mock someOtherFoo() to ensure it gets the correct value for $arg
    $fixture->expects($this->once())
            ->method('someOtherFoo')
            ->with('foo');

    // call someFoo() with the correct $arg
    $fixture->someFoo('foo');
}

这篇关于模拟新类对象调用的方法的单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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