我是单元测试的新手,我在phpunit中理解模拟对象时遇到了问题。 我有以下功能:
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.
我做错了什么?
答案 0 :(得分:7)
您的模拟从未传递给您正在测试的对象。你应该记住的事情是你不要模拟一个类,你嘲笑一个类的对象。所以,你已经创建了一个模拟,然后你必须以某种方式将它传递给你的测试对象。在大多数情况下,您可以通过依赖注入来完成。
在原始类中注入依赖项(例如通过构造函数):
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());