php – 如何抢先模拟由另一个类实例化的类

我怀疑我的问题的“最佳”答案是使用依赖注入并完全避免这个问题.不幸的是我没有那个选择……

我需要为一个类编写一个测试,它会导致第三方库被实例化.我想模拟/存储库类,以便它不会进行实时API调用.

我在CakePHP v3.x框架中使用PHPunit.我能够模拟库并创建存根响应,但这并不妨碍“真实”类被我的测试之外的代码实例化.我考虑过试图在实例化的上游模拟类,但是有很多类,这会使得测试难以置信地编写/维护.

有没有办法以某种方式“存根”类的实例化?类似于我们可以告诉PHP单元期望API调用并预设返回的数据的方式?

解决方法:

使用PHPUnit,您可以获得API类的模拟.然后,您可以指定它将如何与使用的方法和参数进行交互.

以下是PHPunit.de网站的示例(第9章):

public function testObserversAreUpdated()
{
    // Create a mock for the Observer class,
    // only mock the update() method.
    $observer = $this->getMockBuilder('Observer')
                     ->setMethods(array('update'))
                     ->getMock();

    // Set up the expectation for the update() method
    // to be called only once and with the string 'something'
    // as its parameter.
    $observer->expects($this->once())
             ->method('update')
             ->with($this->equalTo('something'));

    // Create a Subject object and attach the mocked
    // Observer object to it.
    $subject = new Subject('My subject');
    $subject->attach($observer);

    // Call the doSomething() method on the $subject object
    // which we expect to call the mocked Observer object's
    // update() method with the string 'something'.
    $subject->doSomething();
}

如果API返回了某些内容,那么您可以将will()添加到第二个语句,如下所示:

   ->will($this->returnValue(TRUE));

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...