代码之家  ›  专栏  ›  技术社区  ›  Knight

如何使用Prophesy在Zend Expressive中对RequestHandlerInterface类进行双重测试?

  •  1
  • Knight  · 技术社区  · 8 年前

    我想做一个单元测试 process() Zend表示应用程序中中间件的方法。要做到这一点,我需要模仿 $delegate 类型为的方法的参数 RequestHandlerInterface 会有办法的 handle() .

    这应该很容易做到,因为我在这个测试中成功地用Prophesy对其他对象进行了模拟:

    每当 句柄() 方法被调用时,我收到以下错误: "Unexpected method call on Double\RequestHandlerInterface\P18:\n - handle(\n Double\ServerRequestInterface\P17:000000004a01de0d000000000617c05e Object (\n 'objectProphecy' => Prophecy\Prophecy\ObjectProphecy Object (*Prophecy*)\n )\n )\nexpected calls were:\n - handle(\n\n )"

    句柄() 上的方法 $mockDelegate 调用时仍抛出错误:

    /**
     * @test
     */
    public function 
    testReturnsRedirectResponseForHandlerWhenNoErrorsFoundRequestTypePOST()
    {
    
        $renderer = $this->prophesize(TemplateRendererInterface::class);
        $renderer
            ->render('app::contract-form-page', [])
            ->willReturn('');
    
        $validateSubmitAction = new ValidateSubmitAction(
            $this->router->reveal(),
            $renderer->reveal(),
            get_class($this->container->reveal()),
            $this->logger->reveal()
        );
    
        $mockRequest = $this->prophesize(ServerRequestInterface::class);
        $mockRequest->getMethod()->willReturn('POST');
        $mockRequest->getBody()->willReturn(
        //create fake object with getContents method
            new class {
                public function getContents(){ return 'location-number=testLoc&contract-number=1234';}
            });
    
        $mockDelegate = $this->prophesize(RequestHandlerInterface::class);
        $mockDelegate->handle()->willReturn('');
    
        $response = $validateSubmitAction->process(
            $mockRequest->reveal(),
            $mockDelegate->reveal()
        );
    
        $this->assertInstanceOf(ValidateSubmitAction::class, $validateSubmitAction);
    }
    

    public function process(ServerRequestInterface $request, RequestHandlerInterface $delegate): ResponseInterface
    {
        ...
        // Delegate on to the handler
        return $delegate->handle($request); //<-- this is where the error occurs in the unit test
    

    我怎样才能准确地模仿 RequestHandlerInterface handle() 用Prophesy方法来实现一个无错误的测试?

    1 回复  |  直到 8 年前
        1
  •  2
  •   xtreamwayz    8 年前

    你有这个: $mockDelegate->handle()->willReturn('');

    $handler->handle(Argument::that([$mockRequest, 'reveal']))->willReturn('');

    在代码中,您希望handle()在没有任何参数的情况下被调用。但它是用模拟请求接口的实例调用的。

    zend-expressive-session :

    public function testMiddlewareCreatesLazySessionAndPassesItToDelegateAndPersistsSessionInResponse()
    {
        $request = $this->prophesize(ServerRequestInterface::class);
        $request
            ->withAttribute(SessionMiddleware::SESSION_ATTRIBUTE, Argument::type(LazySession::class))
            ->will([$request, 'reveal']);
    
        $response = $this->prophesize(ResponseInterface::class);
    
        $handler = $this->prophesize(RequestHandlerInterface::class);
        $handler->handle(Argument::that([$request, 'reveal']))->will([$response, 'reveal']);
    
        $persistence = $this->prophesize(SessionPersistenceInterface::class);
        $persistence
            ->persistSession(
                Argument::that(function ($session) use ($persistence, $request) {
                    $this->assertInstanceOf(LazySession::class, $session);
                    $this->assertAttributeSame($persistence->reveal(), 'persistence', $session);
                    $this->assertAttributeSame($request->reveal(), 'request', $session);
                    return $session;
                }),
                Argument::that([$response, 'reveal'])
            )
            ->will([$response, 'reveal']);
    
        $middleware = new SessionMiddleware($persistence->reveal());
        $this->assertSame($response->reveal(), $middleware->process($request->reveal(), $handler->reveal()));
    }
    
    推荐文章