2014-01-29 81 views
2

我是單元測試新手,並且在理解phpunit中模擬對象時遇到問題。 我有以下功能:PHPUnit模擬方法調用0次,而應該調用一次

public function createPaymentStatement() 
{ 
    $tModel = new \FspInvoice\Model\Transaction(); 
    $paymentsArr = $this->transactionGateway->getTransactionWithStatus($tModel::SETTLED); 
    $result = false; 
    if(is_array($paymentsArr)){ 
      //some code here 
      $result = $psArr; 

    } 

    return $result; 
} 

而現在的單向測試上面的功能:

public function testCreatePaymentStatementWithPaymentsSettledReturnsArray() 
{ 
    $this->transactionGateway = $this->getMockBuilder('FspInvoice\Model\TransactionsTable') 
     ->setMethods(array('getTransactionWithStatus')) 
     ->disableOriginalConstructor() 
     ->getMock(); 
    $this->transactionGateway->expects($this->once()) 
     ->method('getTransactionWithStatus') 
     ->will($this->returnValue(array(0,1,2))); 
    $test = $this->service->createPaymentStatement(); 
    $this->assertTrue(is_array($test)); 
} 

但是當我運行的代碼中,我得到的錯誤:

1)FspInvoiceTest\ServiceTest\PaymentTest::testCreatePaymentStatementWithPaymentsSettledReturnsArray 
Expectation failed for method name is equal to <string:getTransactionWithStatus> when invoked 1 time(s). 
Method was expected to be called 1 times, actually called 0 times. 

我究竟做錯了什麼?

回答

6

您的模擬從未傳遞給您正在測試的對象。你應該記住的是你不嘲笑一個班級,你嘲笑一個班級的對象。所以,你創建了一個模擬,然後你必須以某種方式將它傳遞給你的測試對象。在大多數情況下,你是通過依賴注入來實現的。

在原來的類依賴注入(通過構造函數實例):

class TestedClass 
{ 
    public function __construct(TransactionGateway $transactionGateway) 
    { 
     $this->transactionGateway = $transactionGateway; 
    } 

    public function createPaymentStatement() 
    { 
     // (...) 
    } 
} 

然後在您的測試:

// create a mock as you did 
$transactionGatewayMock = (...) 

// pass the mock into tested object 
$service = new TestedClass($transactionGateway); 

// run test 
$this->assertSomething($service->createPaymentStatement()); 
+1

是的,的確,問題是,我沒有通過嘲笑對象。謝謝 – sica07

+1

「你應該記住的是,你不嘲笑一門課,你嘲笑一門課的對象」+1 –