phpunit测试方法,该方法调用需要模拟的其他类方法 [英] phpunit testing method that calls other class methods which need mock

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

问题描述

我正在尝试创建一个相当标准的单元测试,在其中我调用一个方法并断言它的响应,但是我正在测试的方法在同一类内调用了另一个方法,这有点麻烦.

I'm trying to create a pretty standard unit test where I call a method and assert it's response, however the method I'm testing calls another method inside the same class which does a little bit of heavy lifting.

我想模拟一个方法,但仍然按原样执行我正在测试的方法,仅使用从另一方法的调用返回的模拟值.

I want to mock that one method but still execute the method I'm testing as is, only with the mocked value returned from the call to the other method.

我已经简化了示例,以使其尽可能简单.

I've dumbed down the example to make it as simple as possible.

class MyClass
{

    // I want to test this method, but mock the handleValue method to always return a set value.

    public function testMethod($arg)
    {

        $value = $arg->getValue();

        $this->handleValue($value);

    }


    // This method needs to be mocked to always return a set value.

    public function handleValue($value)
    {

        // Do a bunch of stuff...
        $value += 20;

        return $value;

    }

}

我尝试编写测试.

class MyClassTest extends \PHPUnit_Framework_TestCase
{


    public function testTheTestMethod()
    {

        // mock the object that is passed in as an arg
        $arg = $this->getMockBuilder('SomeEntity')->getMock();
        $arg->expects($this->any())
            ->method('getValue')
            ->will($this->returnValue(10));

        // test handle document()
        $myClass = new MyClass();

        $result = $myClass->testMethod($arg);

        // assert result is the correct
        $this->assertEquals($result, 50);

    }

}

我尝试模拟MyClass对象,但是当我这样做并调用testMethod时,它总是返回null.我需要一种方法来模拟一个方法,但完整保留对象的其余部分.

I have tried mocking the MyClass object, but when I do that and call the testMethod it always returns null. I need a way to mock the one method but leave the rest of the object intact.

推荐答案

您可以模拟要测试的类,并指定要模拟的方法.

You can mock the class that you are testing and specify the method that you want to mock.

$mock = $this->getMockBuilder('MyClass')
    ->setMethods(array('handleValue'))
    ->getMock();

$mock->expects($this->once())
    ->method('handleValue')
    ->will($this->returnValue(23)) //Whatever value you want to return

但是,IMO这不是您测试的最佳方法. 像这样的测试会使重构变得更加困难.您是在指定类的实现,而不是指定类应具有的行为.如果handleValue做了大量复杂的工作,使测试变得困难,请考虑将逻辑移到一个单独的类中并将其注入您的类中.然后,您可以创建该类的模拟并将其传递给testMethod.如果handleValue需要适应其行为,这样做将为您提供使MyClass具有更高可扩展性的附加优势.

However, IMO this is not the best idea for your tests. Testing like this will make refactoring much more difficult. You are specifying the implementation of the class rather than the behavior that the class is supposed to have. If handleValue is doing a lot of complicated work that makes testing difficult, consider moving the logic into a separate class and injecting that into your class. Then you can create a mock of that class and pass it in to testMethod. Doing so will give you the added advantage of making MyClass more extensible if handleValue needs to adapt its behavior.

http://www.oodesign.com/strategy-pattern.html

作为一般规则,您不应模拟正在测试的系统.

As a general rule, you should not mock the system that you are testing.

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

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