创建一个mock类,其方法在实例化时返回值

时间:2013-12-17 20:48:34

标签: php unit-testing phpunit

如何使用一种方法创建一个模拟类(不仅仅是一个模拟对象),实例化后会返回一个可预测的值?

在下面的代码中,我正在测试一个更大的概念(accounts-> preauthorize()),但我需要模拟对象Lookup,以便我可以为我的测试获得可预测的结果。

我正在使用PHPUnit和CakePHP,如果这很重要的话。这是我的情况:

// The system under test
class Accounts
{
    public function preauthorize()
    {
        $obj = new Lookup();
        $result = $obj->get();
        echo $result; // expect to see 'abc'
        // more work done here
    }
}

// The test file, ideas borrowed from question [13389449][1]
class AccountsTest
{
    $foo = $this->getMockBuilder('nonexistent')
        ->setMockClassName('Lookup')
        ->setMethods(array('get'))
        ->getMock();
    // There is now a mock Lookup class with the method get()
    // However, when my code creates an instance of Lookup and calls get(),
    // it returns NULL. It should return 'abc' instead.

    // I expected this to make my instances return 'abc', but it doesn't. 
    $foo->expects($this->any())
        ->method('get')
        ->will($this->returnValue('abc')); 

    // Now run the test on Accounts->preauthorize()
}

1 个答案:

答案 0 :(得分:3)

这里有几个问题,但主要的一点是你在需要它的方法中实例化你的Lookup类。这使得无法模仿。您需要将Lookup实例传递给此方法以解除依赖关系。

class Accounts
{
    public function preauthorize(Lookup $obj)
    {
        $result = $obj->get();
        return $result; // You have to return something here, you can't test echo
    }
}

现在你可以模拟Lookup。

class AccountsTest
{
    $testLookup = $this->getMockBuilder('Lookup')
        ->getMock();

    $testLookup->expects($this->any())
        ->method('get')
        ->will($this->returnValue('abc')); 

    $testAccounts = new Accounts();
    $this->assertEquals($testAccounts->preauthorize($testLookup), 'abc');
}

不幸的是,我无法测试这个测试,但这应该让你朝着正确的方向前进。

显然,Lookup类的单元测试也应该存在。

您可能还会找到我的answer here

相关问题