pamil/prophecy-common

此包已被放弃,不再维护。未建议替代包。

Prophecy 常用辅助类

v0.1.0 2016-05-06 08:34 UTC

This package is auto-updated.

Last update: 2020-12-03 09:48:38 UTC


README

一系列有用的类,用于解决我在使用 PhpSpec 时遇到的一些问题。MIT 许可证。

CompositePromise

允许相同的方法抛出不同的异常,同时返回和抛出异常,并且在不使用 shouldBeCalledTimes() 的情况下限制调用次数。

$collabolator->mockedMethod()->will(
    CompositePromise::it()->willThrow(\LogicException::class)->andThenReturn('value')
);

区别

  • CompositePromise::willReturn()CompositePromise::andThenReturn() 的行为与 MethodProphecy::willReturn() 相同(在 PhpSpec 中:$collabolator->callMethod()->willReturn()

  • CompositePromise::willThrow()CompositePromiser::andThenThrow() 的行为与 MethodProphecy::willThrow() 相同(在 PhpSpec 中:$collabolator->callMethod()->willThrow()),但它们可以接收多个参数,例如 CompositePromise::willThrow(\FirstException::class)->andThenThrow(\SecondException::class) 等于 CompositePromise::willThrow(\FirstException::class, \SecondException::class)

  • CompositePromise::will()CompositePromise::andThen() 的行为与 MethodProphecy::will() 相同,但它们可以像前述方法一样接收多个参数

示例

<?php

namespace spec\example\Pamil\ProphecyCommon;

use example\Pamil\ProphecyCommon\Collaborator;
use example\Pamil\ProphecyCommon\SubjectUnderSpecification;
use Pamil\ProphecyCommon\Promise\CompositePromise;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Prophecy\Promise\ReturnPromise;

/**
 * @mixin SubjectUnderSpecification
 *
 * @author Kamil Kokot <kamil@kokot.me>
 */
final class SubjectUnderSpecificationSpec extends ObjectBehavior
{
    function let(Collaborator $collaborator)
    {
        $this->beConstructedWith($collaborator);
    }

    function it_exact_promise_returns_a_value(Collaborator $collaborator)
    {
        $collaborator->invoke()->will(CompositePromise::it()->willReturn('value'));

        $this->invokeCollabolator()->shouldReturn('value');
    }

    function it_exact_promise_returns_a_few_values(Collaborator $collaborator)
    {
        $collaborator->invoke()->will(CompositePromise::it()->willReturn('value1', 'value2'));

        $this->invokeCollabolator()->shouldReturn('value1');
        $this->invokeCollabolator()->shouldReturn('value2');
    }

    function it_exact_promise_throws_an_exception(Collaborator $collaborator)
    {
        $collaborator->invoke()->will(CompositePromise::it()->willThrow(\Exception::class));

        $this->shouldThrow(\Exception::class)->during('invokeCollabolator');
    }

    function it_exact_promise_returns_a_value_and_then_throws_an_exception(Collaborator $collaborator)
    {
        $collaborator->invoke()->will(
            CompositePromise::it()->willReturn('value')->andThenThrow(\Exception::class)
        );

        $this->invokeCollabolator()->shouldReturn('value');
        $this->shouldThrow(\Exception::class)->during('invokeCollabolator');
    }

    function it_exact_promise_returns_a_few_values_and_then_throws_an_exception(Collaborator $collaborator)
    {
        $collaborator->invoke()->will(
            CompositePromise::it()->willReturn('value1', 'value2')->andThenThrow(\Exception::class)
        );

        $this->invokeCollabolator()->shouldReturn('value1');
        $this->invokeCollabolator()->shouldReturn('value2');
        $this->shouldThrow(\Exception::class)->during('invokeCollabolator');
    }

    function it_exact_promise_throws_an_exception_and_then_returns_a_value(Collaborator $collaborator)
    {
        $collaborator->invoke()->will(
            CompositePromise::it()->willThrow(\Exception::class)->andThenReturn('value')
        );

        $this->shouldThrow(\Exception::class)->during('invokeCollabolator');
        $this->invokeCollabolator()->shouldReturn('value');
    }

    function it_exact_promise_throws_an_exception_and_then_returns_a_few_values(Collaborator $collaborator)
    {
        $collaborator->invoke()->will(
            CompositePromise::it()->willThrow(\Exception::class)->willReturn('value1', 'value2')
        );

        $this->shouldThrow(\Exception::class)->during('invokeCollabolator');
        $this->invokeCollabolator()->shouldReturn('value1');
        $this->invokeCollabolator()->shouldReturn('value2');
    }

    function it_exact_promise_throws_two_different_exceptions(Collaborator $collaborator)
    {
        $collaborator->invoke()->will(
            CompositePromise::it()->willThrow(\LogicException::class, \RuntimeException::class)
        );

        $this->shouldThrow(\LogicException::class)->during('invokeCollabolator');
        $this->shouldThrow(\RuntimeException::class)->during('invokeCollabolator');
    }

    function it_exact_promise_performs_a_custom_promise(Collaborator $collaborator)
    {
        $collaborator->invoke()->will(
            CompositePromise::it()->will(new ReturnPromise(['value']))
        );

        $this->invokeCollabolator()->shouldReturn('value');
    }

    function it_exact_promise_performs_a_few_custom_promises(Collaborator $collaborator)
    {
        $collaborator->invoke()->will(
            CompositePromise::it()->will(new ReturnPromise(['value1']), new ReturnPromise(['value2']))
        );

        $this->invokeCollabolator()->shouldReturn('value1');
        $this->invokeCollabolator()->shouldReturn('value2');
    }

    function it_exact_promise_returns_a_value_and_performs_a_custom_promise(Collaborator $collaborator)
    {
        $collaborator->invoke()->will(
            CompositePromise::it()->willReturn('return value')->andThen(new ReturnPromise(['custom promise value']))
        );

        $this->invokeCollabolator()->shouldReturn('return value');
        $this->invokeCollabolator()->shouldReturn('custom promise value');
    }

    function it_exact_promise_executes_the_last_promise_if_called_more_times_than_explicitly_defined(Collaborator $collaborator)
    {
        $collaborator->invoke()->will(
            CompositePromise::it()->willReturn('value1', 'value2')
        );

        $this->invokeCollabolator()->shouldReturn('value1');
        $this->invokeCollabolator()->shouldReturn('value2');
        $this->invokeCollabolator()->shouldReturn('value2');
    }
}