2014-03-27 56 views
0

另一个类中使用的PHPUnit模拟方法? 例子:另一个类中使用的PHPUnit模拟方法

class Main { 
    function makePayment() { 
    $pp = new PayPalSOAPSomeClass(); 
    return $pp->doExpressCheckout(); 
    } 
} 

在测试我想测试我的主类和模拟doExpressCheckout()方法,我不工作的代码进行测试:

public function testStub() { 
     $stub = $this->getMock('PayPalSOAPSomeClass'); 
     $stub->expects($this->any()) 
      ->method('doExpressCheckout') 
      ->will($this->returnValue(false)); 
     $pp = new Main; 
     $this->assertEquals(true, $pp->doExpressCheckout()); 
    } 

回答

2

你必须测试的主类的问题。第一个问题是它在内部创建一个对象。你需要修改这个类来使用依赖注入。你的makePayment()应该接受一个PayPalSOAPSomeClass对象。

function makePayment(PayPalSOAPSomeClass $pp) 
{ 
    return $pp->doExpressCheckout(); 
} 

在主类中,你可以修改它使用构造函数依赖注入,或一个setter依赖注入,这是比makePayment更好。然后,你引用内部对象。

例如:

class Main { 
    private $svc; 

    // Constructor Injection, pass the PayPalSOAPSomeClass object here 
    public function __construct($Service = NULL) 
    { 
     if(! is_null($Service)) 
     { 
      if($Service instanceof PayPalSOAPSomeClass) 
      { 
       $this->SetPayPalSOAP($Service); 
      } 
     } 
    } 

    function SetPayPalSOAP(PayPalSOAPSomeClass $Service) 
    { 
     $this->svc = $Service; 
    } 

    function makePayment() { 
     $pp = $this->svc; 
     return $pp->doExpressCheckout(); 
    } 
} 

测试:

public function testStub()  
{ 
    $stub = $this->getMock('PayPalSOAPSomeClass'); 
    $stub->expects($this->any()) 
     ->method('doExpressCheckout') 
     ->will($this->returnValue(false)); 
    $pp = new Main($stub); 
    $this->assertEquals(true, $pp->doExpressCheckout()); 
} 
+0

如果我不喜欢你说,为什么我需要嘲弄?我可以写成$ this-> assertEquals(true,false);因为在模拟我设置虚假的返回值 – Actimele

+0

DI后,注入类具有公共属性,我可以如何设置此属性? – Actimele

+0

是的,你可以,而且工作范围非常有限。之后,您将希望更彻底地测试此代码并获得更复杂的返回结果,例如响应,错误等...... Mocking允许您的代码仍然调用正确的内部函数,以确保代码在返回的数据上相应地运行。你可以得到参考号码,并确保它们是正确的。帐户余额,处理错误等...所有这些都可能由模拟程序返回,您的库代码会测试它以确保您的模块正确处理所有响应。 –

相关问题