如何使用Mockery部分模拟一个类?

时间:2013-07-29 20:49:57

标签: php laravel laravel-4 mockery

我有这堂课:

class PagSeguro {

    public function pay()
    {
        if ( ! $this->checkAllData() )
        {
            return false;
        }

        return $this->buildPaymentURL();
    }

    private function checkAllData()
    {
        return true;
    }

    private function buildPaymentURL()
    {
        echo "not cool!\n\n";

        return true;
    }

}

对此进行测试:

public function testPagSeguroPaymentData()
{
    $m = m::mock('PagSeguro[buildPaymentURL]');

    $m->shouldReceive('buildPaymentURL')
        ->once()
        ->andReturn('http://');

    $this->assertEquals($m->pay(), 'http://');
}

如果我是var_dump($ m),我会看到模拟的方法:

    'buildPaymentURL' =>
    class Mockery\ExpectationDirector#1507 (5) {
      protected $_name =>
      string(15) "buildPaymentURL"
      protected $_mock =>
              ...

      protected $_expectations =>
      array(1) {
        ...
      }
      protected $_expectedOrder =>
      NULL
      protected $_defaults =>
      array(0) {
        ...
      }
    }
  }

但是当测试执行时,它不是嘲笑的而是真实的。除非我重命名

private function buildPaymentURL_RENAMED() {}

然后我变绿了。

任何人都可以使用Mockery向我展示做这些部分模拟的正确方法吗?

1 个答案:

答案 0 :(得分:4)

我认为你不能让这个方法成为private,因为当你输入真实对象的代码时,对$this->buildPaymentURL的任何调用必须以真正的私有方法结束。

让它受到保护。这样,mock就可以扩展你的类并覆盖函数。

另一方面,如果需要这样的部分嘲笑,我总会有一点不好的感觉。它们很可能是糟糕设计的标志。似乎这个私有方法应该包含在它自己的一个对象中,它专门处理URL创建(并且可以单独测试),而你现在测试的这个类应该只能完全模拟注入的新类。