我正在尝试在 Zend Framework 2.3 中的 Controller 上运行测试。
我测试的 Action 是这样的:
public function listAction() {
// optional filtering
$filter = $this->params('filter'); // filter type
// params from JSON
$jsonPost = $this->getRequest()->getContent();
$params = json_decode($jsonPost);
$param1 = isset($params->query1) ? $params->query1 : NULL;
$param2 = isset($params->query2) ? $params->query2 : NULL;
$json = Array( // json container
'status' => TRUE,
'data' => Array(),
);
try {
// get data from Model
$list = new Mapping\Books\Listing();
if( !empty($filter)) { // optional filtering
$list->addFilter($filter, $param1, $param2);
}
$data = $list->setOrder()->getList();
// final data mapping to JSON and formating
foreach($data as $isbn => $book) {
$json['data'][$isbn] = Array(
'ISBN' => $book->getISBN(),
'title' => $book->getTitle(),
'rating' => $book->getRating(),
'release_date' => $book->getReleaseDate()->format('F Y'),
'authors' => Array() // multiple
);
// final authors mapping
foreach($book->getAuthors() as $author) {
$json['data'][$isbn]['authors'][] = Array(
'author_id' => $author->getId(),
'author_name' => $author->getName()
);
}
}
} catch(Exception $e) {
$json = Array(
'status' => FALSE,
'error' => $e->getMessage()
);
}
return new JsonModel( $json );
}
我的测试方法是这样的:
public function testListActionWithoutParams()
{
// object mocking
$listingMock = $this->getMockBuilder('Books\Model\Mapping\Books\Listing')
->disableOriginalConstructor()
->setMethods(Array('getData', 'setOrder'))
->getMock();
$listingMock->expects($this->once())->method('setOrder')
->will($this->returnSelf());
$listingMock->expects($this->once())->method('getData')
->willReturn( Array() ); // for testing is enough
$serviceManager = $this->getApplicationServiceLocator();
$serviceManager->setAllowOverride(true);
$serviceManager->setService('Books\Model\Mapping\Books\Listing', $listingMock);
// dispatch
$this->dispatch('/books');
// routing tests
$this->assertResponseStatusCode(200);
$this->assertModuleName('Books');
$this->assertControllerName('Books\Controller\Index');
$this->assertControllerClass('IndexController');
$this->assertActionName('list');
$this->assertMatchedRouteName('list');
// header tests
$this->assertResponseHeaderContains('Content-type', 'application/json; charset=utf-8');
}
我想我在这里误解了一些东西。我的理解是,serviceManager 也会“通知”自动加载器,实际调用的类应该替换为模拟对象,但它没有。
请问如何用 mocked 替换我的对象?
最佳答案
首先你的 Controller 有很多逻辑,哪里不对。
其次,我只能给你代码的工作流程:
在您的 Controller 中,您需要一个将返回列表对象的方法,因此符合:
// get data from Model
$list = new Mapping\Books\Listing();
应该是新的方法调用:
// get data from Model
$list = $this->getListing();
方法:
public function getListing()
{
return new Mapping\Books\Listing();
}
现在您需要在 Controller 中模拟此方法。模拟方法返回的对象应该是您模拟的 Mapping\Books\Listing
对象。
关于testing - ZF2 测试 - serviceManager 忽略的模拟对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28529337/