簡體   English   中英

PHP 單元故障測試

[英]PHP unit failure testing

我必須測試這個類的失敗條件

<?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.'
            ]);
        }
    }
}

以下是我寫的測試用例

<?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 中遇到的失敗

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.

任何人都可以澄清我在這里做錯了什么嗎?

你的setUp()方法在每次測試之前都會被調用,所以testHandleSynchronousMessageForFailure()也期望sendNonBlockingAsynchronous()被調用:

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

即使您在失敗測試中對其調用shouldNotBeCalled() 因此,將shouldBeCalled()調用移動到testHandleSynchronousMessageForSuccess() ,這樣它就會期望它在成功測試中被調用,而不是在失敗測試中被調用。

您還應該告訴 PHPUnit 在失敗測試中期待IdNotDefinedException

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM