PHP单元故障测试 [英] PHP unit failure testing

查看:80
本文介绍了PHP单元故障测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须测试此类的失败情况

I have to test this class for failure condition

<?php
namespace Gpx\Handlers;
use Gpx\EntityInfrastructure\Model\Events\PlatformSessionInitiated;
use Gpx\EntityInfrastructure\Model\Payload;
use Gpx\Hfx\Framework\MessageTransportApplication\Handler\SynchronousHandlerInterface;
use Gpx\Hfx\Framework\MessageTransportApplication\Handler\MessageHandlingContextInterface;
use Gpx\HfxEventSourcing\HfxAggregateRoot;
use Gpx\HfxEventSourcing\HfxEventMetadata;
use Gpx\HfxEventSourcing\HfxProjectionHelper;
use Gpx\HfxEventSourcing\HfxRepository;
use Gpx\Hfx\MessageTransport\Response\SendableResponse;
use Gpx\Exceptions\IdNotDefinedException;
use Gpx\Exceptions\AggregateNotFoundException;

class BroadcastPlatformSessionInitiated implements SynchronousHandlerInterface
{

    /** @var HfxRepository */
    private $repository;

    /** @var  HfxProjectionHelper */
    private $projectionHelper;


    public function __construct(HfxRepository $repository, HfxProjectionHelper $projectionHelper)
    {
        $this->repository = $repository;
        $this->projectionHelper = $projectionHelper;
    }

    /*
     * @param MessageHandlingContextInterface $context
     * @return SendableResponse
     */
    public function handleSynchronousMessage(MessageHandlingContextInterface $context): SendableResponse
    {
        try {
            $content = $context->message();
            $header = $context->rawMessage()->header();

            $metadata = HfxEventMetadata::fromHfxHeader($header);
            $payload = Payload::fromMessageContent($content);

            $roleAggregate = HfxAggregateRoot::createEntityFromEvent(PlatformSessionInitiated::class, $payload, $metadata);
            $this->repository->save($roleAggregate);

            $currentEvent = $roleAggregate->currentEvent();
            $context->sendNonBlockingAsynchronous('platform_session_initiated', $currentEvent);

            $this->projectionHelper->updateReadModel(HfxAggregateRoot::class);

            return SendableResponse::answerTo($context->rawMessage(), 1000, [
                'responseMessage' => 'Success',
                'event' => $currentEvent
            ]);
        } catch (IdNotDefinedException $e) {
            return SendableResponse::answerTo($context->rawMessage(), 2000, [
                'responseMessage' => 'Failure. Session Id is not defined.'
            ]);
        }
    }
}

以下是我编写的测试用例

Following is the test case I have written

<?php

namespace Gpx\Tests\Handlers;

use Ramsey\Uuid\Uuid;
use Gpx\Json\JsonEncode;
use Prophecy\Argument;
use PHPUnit\Framework\TestCase;
use Gpx\HfxEventSourcing\HfxProjectionHelper;
use Gpx\HfxEventSourcing\HfxRepository;
use Gpx\Hfx\Framework\MessageTransportApplication\Handler\MessageHandlingContextInterface;
use Gpx\Handlers\BroadcastPlatformSessionInitiated;
use Gpx\Hfx\MessageTransport\Message\ReceivedMessage;
use Gpx\Exceptions\IdNotDefinedException;

class BroadcastPlatformSessionInitiatedTest extends TestCase
{
    /** @var HfxRepository */
    private $repository;

    /** @var  HfxProjectionHelper */
    private $projectionHelper;

    /** @var  MessageHandlingContext */
    private $context;

    /**
     * This will run before each test
     */
    public function setUp()
    {

        // Expected return value of message() function of $this->context
        $expectedReturnValue = [
            "session_id" => "1a92-4376-a8eb-deaf208ssess11",
            "user_id" => "we",
            "access_jwt" => "C",
            "access_token" => "john@gmail.com",
            "refresh_token" => "C",
            "refresh_token_expires" => "john@gmail.com"
        ];

        // Expected return value of rawMessage() function of $this->context
        $headerResponseExpected = [
            'header' => [
                'version' => '2.0',
                'originId' => (string)Uuid::uuid4(),
                'destination' => 'application/meta@1.0.0',
                'sent' => '2017-12-19T10:12:37.941+00:00'
            ],
            'content' => [
                'session_id' => null,
                'title' => "A task's title."
            ]
        ];

        // Prediction of $this->context object starts
        $this->context = $this->prophesize(MessageHandlingContextInterface::class);
        $this->context->message(Argument::any())->willReturn($expectedReturnValue);

        $encodedMessage = new JsonEncode($headerResponseExpected);
        $rawMessage = ReceivedMessage::fromEncodedMessage($encodedMessage->asString());
        $this->context->rawMessage()->willReturn($rawMessage);

        $this->context->sendNonBlockingAsynchronous('platform_session_initiated', Argument::type("array"))
            ->shouldBeCalled();
        // Prediction of $this->context object ends
    }

    // We have to test handleSynchronousMessage handler whether it is returning sendable response with certain properties in it.
    public function testHandleSynchronousMessageForSuccess()
    {

        // Prophecy means prediction of the future object
        $this->ravenRepository = $this->prophesize(HfxRepository::class);
        $this->ravenRepository->save(Argument::any())
            ->shouldBeCalled();

        // Mocking HfxProjectionHelper and calling the method updateReadModel which will return the string UpdateReadModel
        $this->projectionHelper = $this->createMock(HfxProjectionHelper::class);
        $this->projectionHelper->method('updateReadModel')
            ->willReturn('UpdateReadModel');

        // Actual calling
        $broadcastPlatformSessionInitiated = new BroadcastPlatformSessionInitiated($this->ravenRepository->reveal(), $this->projectionHelper);
        $response = $broadcastPlatformSessionInitiated->handleSynchronousMessage($this->context->reveal());

        $this->assertInstanceOf('Gpx\Hfx\MessageTransport\Response\SendableResponse', $response);
        $this->assertArrayHasKey("responseMessage", $response->content()->data());
        $this->assertArrayHasKey("event", $response->content()->data());
        $this->assertEquals("Success", $response->content()->data()['responseMessage']);

    }

    // We have to test handleSynchronousMessage handler whether it is returning sendable response with certain properties in it.
    public function testHandleSynchronousMessageForFailure()
    {

        // Expected return value of message() function of $this->context
        $expectedReturnValue = [
            "session_id" => null,
            "user_id" => "we",
            "access_jwt" => "C",
            "access_token" => "john@gmail.com",
            "refresh_token" => "C",
            "refresh_token_expires" => "john@gmail.com"
        ];

        // Expected return value of rawMessage() function of $this->context
        $headerResponseExpected = [
            'header' => [
                'version' => '2.0',
                'originId' => (string)Uuid::uuid4(),
                'destination' => 'application/meta@1.0.0',
                'sent' => '2017-12-19T10:12:37.941+00:00'
            ],
            'content' => [
                'session_id' => '1a92-4376-a8eb-deaf208ssess11',
                'title' => "A task's title."
            ]
        ];

        // Prediction of $this->context object starts
        $this->context = $this->prophesize(MessageHandlingContextInterface::class);
        $this->context->message(Argument::any())->willReturn($expectedReturnValue);

        $encodedMessage = new JsonEncode($headerResponseExpected);
        $rawMessage = ReceivedMessage::fromEncodedMessage($encodedMessage->asString());
        $this->context->rawMessage()->willReturn($rawMessage);

        $this->context->sendNonBlockingAsynchronous('platform_session_initiated', Argument::type("array"))->shouldNotBeCalled();
        // Prediction of $this->context object ends

        // Prophecy means prediction of the future object
        $this->ravenRepository = $this->prophesize(HfxRepository::class);


        // Mocking HfxProjectionHelper and calling the method updateReadModel which will return the string UpdateReadModel
        $this->projectionHelper = $this->createMock(HfxProjectionHelper::class);
        $this->projectionHelper->method('updateReadModel')->willReturn('UpdateReadModel');

        // Actual calling
        $broadcastPlatformSessionInitiated = new BroadcastPlatformSessionInitiated($this->ravenRepository->reveal(), $this->projectionHelper);
        $response = $broadcastPlatformSessionInitiated->handleSynchronousMessage($this->context->reveal());

        $this->assertInstanceOf('Gpx\Hfx\MessageTransport\Response\SendableResponse', $response);
        $this->assertArrayHasKey("responseMessage", $response->content()->data());
        $this->assertEquals("Failure. Session Id is not defined.", $response->content()->data()['responseMessage']);

    }
}

这是我遇到的testHandleSynchronousMessageForFailure失败

This is the failure I am getting for testHandleSynchronousMessageForFailure

Gpx\Tests\Handlers\BroadcastPlatformSessionInitiatedTest::testHandleSynchronousMessageForFailure
Some predictions failed:
  Double\MessageHandlingContextInterface\P3:
    No calls have been made that match:
      Double\MessageHandlingContextInterface\P3->sendNonBlockingAsynchronous(exact("platform_session_initiated"), type(array))
    but expected at least one.

FAILURES!
Tests: 3, Assertions: 18, Failures: 1.

有人可以在这里澄清我在做什么错吗?

Could any one please clarify what I am doing wrong here?

推荐答案

在每次 测试之前,您的setUp()方法都会被调用,因此testHandleSynchronousMessageForFailure()也希望sendNonBlockingAsynchronous()被调用:

Your setUp() method gets called before every test, so testHandleSynchronousMessageForFailure() is also expecting sendNonBlockingAsynchronous() to be called:

$this->context->sendNonBlockingAsynchronous('platform_session_initiated', Argument::type("array"))
        ->shouldBeCalled();

即使您在失败测试中调用shouldNotBeCalled(),也是如此.因此,将shouldBeCalled()调用移至testHandleSynchronousMessageForSuccess(),这样它将期望在成功测试中将其调用,而在失败测试中将其 not 调用.

Even if you call shouldNotBeCalled() on it in the failure test. So, move the shouldBeCalled() call to the testHandleSynchronousMessageForSuccess(), that way it will expect it to be called in the success test, and not to be called in the failure test.

您还应该告诉PHPUnit在失败测试中期望IdNotDefinedException:

You should also tell PHPUnit to expect an IdNotDefinedException in the failure test:

$this->expectException(Gpx\Exceptions\IdNotDefinedException::class);

这篇关于PHP单元故障测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆