【问题标题】:ZF2 testing - mock object ignored by serviceManagerZF2 测试 - serviceManager 忽略的模拟对象
【发布时间】:2015-04-16 06:00:27
【问题描述】:

我正在尝试在 Zend Framework 2.3 中的控制器上运行测试。

我测试的操作如下所示:

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 也会“通知”自动加载器,实际调用的类应该被模拟对象替换,但事实并非如此。

请问如何用模拟对象替换我的对象?

【问题讨论】:

  • 您必须将模拟类注入对象。例如。使用 DI。
  • 您能否在上述情况下提供如何实现这一目标?我现在正在和服务经理一起玩,但即使在特殊情况下,仍然没有运气更换它,谢谢

标签: testing zend-framework2 mocking phpunit


【解决方案1】:

首先你的控制器有很多逻辑,什么是不正确的。

其次,我只能给你代码的工作流程:

在您的控制器中,您需要一个返回列表对象的方法,因此请按以下顺序进行:

// get data from Model
$list = new Mapping\Books\Listing();

应该是新的方法调用:

// get data from Model
$list = $this->getListing();

以及方法:

public function getListing()
{
    return new Mapping\Books\Listing();
}

现在您需要在控制器中模拟此方法。而被模拟方法返回的对象应该是你模拟的Mapping\Books\Listing 对象。

【讨论】:

  • 谢谢,同时我做到了,可以说,类似的方式,通过使用提供列表类的工厂对象并通过 SM 传递它。所以可以说我可以接受你的回答:)
  • 顺便说一句,Controller 中的逻辑不是“真实”逻辑 - 只是 JSON 输出的格式。我认为最好在控制器中进行最终格式化,而不是在数据库服务中进行硬编码:)
  • 我不确定我是否理解您想要做什么,但是当您使用工厂时,您也可以返回 mocked Listing
  • 关于 btw,应该有特殊的类,一些帮助器等将格式化输出。控制器只负责获取客户端的请求并提出。
猜你喜欢
  • 2013-10-28
  • 1970-01-01
  • 1970-01-01
  • 2019-04-13
  • 2013-09-12
  • 1970-01-01
  • 1970-01-01
  • 2019-10-27
  • 1970-01-01
相关资源
最近更新 更多