コード例 #1
0
def test_when_then_return_multiple_values(
    decoy: Decoy,
    spy_log: SpyLog,
    stub_store: StubStore,
    subject: DecoyCore,
) -> None:
    """It should add multiple return values to a stub."""
    rehearsal = WhenRehearsal(spy_id=1,
                              spy_name="my_spy",
                              payload=SpyCall(args=(), kwargs={}))
    decoy.when(spy_log.consume_when_rehearsal(
        ignore_extra_args=False)).then_return(rehearsal)

    result = subject.when(0, ignore_extra_args=False)
    result.then_return(42, 43, 44)

    decoy.verify(
        stub_store.add(
            rehearsal=rehearsal,
            behavior=StubBehavior(return_value=44, once=False),
        ),
        stub_store.add(
            rehearsal=rehearsal,
            behavior=StubBehavior(return_value=43, once=True),
        ),
        stub_store.add(
            rehearsal=rehearsal,
            behavior=StubBehavior(return_value=42, once=True),
        ),
    )
コード例 #2
0
def test_spy_prop_get(
    decoy: Decoy,
    call_handler: CallHandler,
    spy_creator: SpyCreator,
    spec: Spec,
) -> None:
    """It should record a property get call."""
    subject = Spy(spec=spec,
                  call_handler=call_handler,
                  spy_creator=spy_creator)

    decoy.when(spec.get_name()).then_return("spy_name")
    decoy.when(
        call_handler.handle(
            SpyEvent(
                spy_id=id(subject),
                spy_name="spy_name",
                payload=SpyPropAccess(
                    prop_name="some_property",
                    access_type=PropAccessType.GET,
                ),
            ), )).then_return(CallHandlerResult(42))

    result = subject.some_property

    assert result == 42
コード例 #3
0
ファイル: test_decoy.py プロジェクト: mcous/decoy
async def test_async_context_manager_mock(decoy: Decoy) -> None:
    """It should be able to mock an async context manager."""
    class _ValueReader(ContextManager[Any]):
        async def __aenter__(self) -> "_ValueReader":
            ...

        async def __aexit__(self, *args: Any) -> None:
            ...

        def get_value(self) -> int:
            ...

    value_reader = decoy.mock(cls=_ValueReader)

    def _handle_enter() -> _ValueReader:
        decoy.when(value_reader.get_value()).then_return(42)
        return value_reader

    def _handle_exit(*args: Any) -> None:
        decoy.when(value_reader.get_value()).then_raise(
            AssertionError("Context manager exited"))

    decoy.when(await value_reader.__aenter__()).then_do(_handle_enter)
    decoy.when(await value_reader.__aexit__(None, None,
                                            None)).then_do(_handle_exit)

    async with value_reader as subject:
        result = subject.get_value()

    assert result == 42

    with pytest.raises(AssertionError, match="exited"):
        subject.get_value()
コード例 #4
0
def test_spy_prop_delete(
    decoy: Decoy,
    call_handler: CallHandler,
    spy_creator: SpyCreator,
    spec: Spec,
) -> None:
    """It should record a property set call."""
    decoy.when(spec.get_name()).then_return("spy_name")

    subject = Spy(spec=spec,
                  call_handler=call_handler,
                  spy_creator=spy_creator)
    subject.some_property = 42
    del subject.some_property

    assert subject.some_property != 42

    decoy.verify(
        call_handler.handle(
            SpyEvent(
                spy_id=id(subject),
                spy_name="spy_name",
                payload=SpyPropAccess(
                    prop_name="some_property",
                    access_type=PropAccessType.DELETE,
                ),
            ), ))
コード例 #5
0
ファイル: test_decoy.py プロジェクト: mcous/decoy
def test_property_getter_stub_then_raise(decoy: Decoy) -> None:
    """It should be able to stub a property getter to raise."""
    subject = decoy.mock()

    decoy.when(subject.prop_name).then_raise(ValueError("oh no"))

    with pytest.raises(ValueError, match="oh no"):
        subject.prop_name
コード例 #6
0
ファイル: test_decoy.py プロジェクト: mcous/decoy
def test_property_getter_stub_then_return_multiple(decoy: Decoy) -> None:
    """It should be able to stub a property getter with multiple return values."""
    subject = decoy.mock()
    decoy.when(subject.prop_name).then_return(43, 44)

    assert subject.prop_name == 43
    assert subject.prop_name == 44
    assert subject.prop_name == 44
コード例 #7
0
ファイル: test_decoy.py プロジェクト: mcous/decoy
def test_when_then_raise(decoy: Decoy) -> None:
    """It should be able to configure a stub raise with a rehearsal."""
    subject = decoy.mock(func=some_func)

    decoy.when(subject("goodbye")).then_raise(ValueError("oh no"))

    with pytest.raises(ValueError, match="oh no"):
        subject("goodbye")
コード例 #8
0
ファイル: test_decoy.py プロジェクト: mcous/decoy
def test_decoy_creates_specless_async_spy(decoy: Decoy) -> None:
    """It should be able to create an async specless spy."""
    subject = decoy.mock(is_async=True)
    assert isinstance(subject, AsyncSpy)

    # test deprecated create_decoy_func method
    subject = decoy.create_decoy_func(is_async=True)
    assert isinstance(subject, AsyncSpy)
コード例 #9
0
ファイル: test_decoy.py プロジェクト: mcous/decoy
def test_property_deleter_stub_then_rase(decoy: Decoy) -> None:
    """It should be able to stub a property deleter to raise."""
    subject = decoy.mock()
    prop_rehearser = decoy.prop(subject.prop_name)

    decoy.when(prop_rehearser.delete()).then_raise(ValueError("oh no"))

    with pytest.raises(ValueError, match="oh no"):
        del subject.prop_name
コード例 #10
0
ファイル: test_decoy.py プロジェクト: mcous/decoy
def test_property_getter_stub_reconfigure(decoy: Decoy) -> None:
    """It should be able to reconfigure a property getter."""
    subject = decoy.mock()

    decoy.when(subject.prop_name).then_return(42)
    assert subject.prop_name == 42

    decoy.when(subject.prop_name).then_return(43)
    assert subject.prop_name == 43
コード例 #11
0
ファイル: test_decoy.py プロジェクト: mcous/decoy
def test_property_getter_stub_then_do(decoy: Decoy) -> None:
    """It should be able to stub a property getter to act."""
    def _handle_get(*args: Any, **kwargs: Any) -> int:
        return 84

    subject = decoy.mock()
    decoy.when(subject.prop_name).then_do(_handle_get)

    assert subject.prop_name == 84
コード例 #12
0
ファイル: test_decoy.py プロジェクト: mcous/decoy
def test_reset(decoy: Decoy) -> None:
    """It should be able to reset its state."""
    subject = decoy.mock(cls=SomeClass)

    subject.foo("hello")
    decoy.reset()

    with pytest.raises(AssertionError):
        decoy.verify(subject.foo("hello"))
コード例 #13
0
ファイル: test_decoy.py プロジェクト: mcous/decoy
def test_decoy_creates_func_spy(decoy: Decoy) -> None:
    """It should be able to create a Spy from a function."""
    subject = decoy.mock(func=some_func)

    assert isinstance(subject, Spy)

    # test deprecated create_decoy_func method
    subject = decoy.create_decoy_func(spec=some_func)

    assert isinstance(subject, Spy)
コード例 #14
0
ファイル: test_decoy.py プロジェクト: mcous/decoy
async def test_verify_async(decoy: Decoy) -> None:
    """It should be able to configure a verification with an async rehearsal."""
    subject = decoy.mock(cls=SomeAsyncClass)

    await subject.foo("hello")

    decoy.verify(await subject.foo("hello"))

    with pytest.raises(AssertionError):
        decoy.verify(await subject.foo("goodbye"))
コード例 #15
0
def test_create_async_spy(decoy: Decoy, call_handler: CallHandler) -> None:
    """It should get default configurations from the spec."""
    spec = decoy.mock(cls=Spec)

    decoy.when(spec.get_is_async()).then_return(True)

    subject = SpyCreator(call_handler=call_handler)
    result = subject.create(spec=spec)

    assert isinstance(result, AsyncSpy)
コード例 #16
0
ファイル: test_decoy.py プロジェクト: mcous/decoy
async def test_when_async(decoy: Decoy) -> None:
    """It should be able to stub an async method."""
    subject = decoy.mock(cls=SomeAsyncClass)

    decoy.when(await subject.foo("hello")).then_return("world")
    decoy.when(await subject.bar(0, 1.0, "2")).then_raise(ValueError("oh no"))

    assert await subject.foo("hello") == "world"

    with pytest.raises(ValueError, match="oh no"):
        await subject.bar(0, 1.0, "2")
コード例 #17
0
ファイル: test_decoy.py プロジェクト: mcous/decoy
def test_when_ignore_extra_args(decoy: Decoy) -> None:
    """It should be able to ignore extra args in a stub rehearsal."""
    def _get_a_thing(id: str, default: Optional[int] = None) -> int:
        raise NotImplementedError("intentionally unimplemented")

    subject = decoy.mock(func=_get_a_thing)

    decoy.when(subject("some-id"), ignore_extra_args=True).then_return(42)

    result = subject("some-id", 101)
    assert result == 42
コード例 #18
0
ファイル: test_decoy.py プロジェクト: mcous/decoy
def test_property_setter_stub_then_raise(decoy: Decoy) -> None:
    """It should be able to stub a property setter to raise."""
    subject = decoy.mock()
    prop_rehearser = decoy.prop(subject.prop_name)

    decoy.when(prop_rehearser.set(42)).then_raise(ValueError("oh no"))

    subject.prop_name = 41
    assert subject.prop_name == 41

    with pytest.raises(ValueError, match="oh no"):
        subject.prop_name = 42
コード例 #19
0
ファイル: test_decoy.py プロジェクト: mcous/decoy
def test_decoy_creates_spy(decoy: Decoy) -> None:
    """It should be able to create a Spy from a class."""
    subject = decoy.mock(cls=SomeClass)

    assert isinstance(subject, SomeClass)
    assert isinstance(subject, Spy)

    # test deprecated create_decoy method
    subject = decoy.create_decoy(spec=SomeClass)

    assert isinstance(subject, SomeClass)
    assert isinstance(subject, Spy)
コード例 #20
0
ファイル: test_decoy.py プロジェクト: mcous/decoy
def test_decoy_creates_specless_spy(decoy: Decoy) -> None:
    """It should be able to create a spec-less spy."""
    subject = decoy.mock()
    assert isinstance(subject, Spy)

    # test deprecated create_decoy_func method
    subject = decoy.create_decoy_func()
    assert isinstance(subject, Spy)

    # test naming the spy
    subject = decoy.mock(name="spy_name")
    assert repr(subject) == "<Decoy mock `spy_name`>"
コード例 #21
0
ファイル: test_decoy.py プロジェクト: mcous/decoy
def test_when_then_return(decoy: Decoy) -> None:
    """It should be able to configure a stub return with a rehearsal."""
    subject = decoy.mock(func=some_func)

    decoy.when(subject("hello")).then_return("hello world")

    result = subject(val="hello")
    assert result == "hello world"

    result = subject(val="hello")
    assert result == "hello world"

    result = subject("asdfghjkl")
    assert result is None
コード例 #22
0
def test_mock_with_name(
    decoy: Decoy,
    spy_creator: SpyCreator,
    call_handler: CallHandler,
    subject: DecoyCore,
) -> None:
    """It should create a generic spy by default."""
    spy = decoy.mock(cls=Spy)

    decoy.when(spy_creator.create(spec=None, name="my-spy",
                                  is_async=False)).then_return(spy)

    result = subject.mock(name="my-spy")

    assert result is spy
コード例 #23
0
ファイル: test_decoy.py プロジェクト: mcous/decoy
def test_when_then_do(decoy: Decoy) -> None:
    """It should be able to configure a stub action with a rehearsal."""
    subject = decoy.mock(func=some_func)
    action_result = None

    def _then_do_action(arg: str) -> str:
        nonlocal action_result
        action_result = arg
        return "hello from the other side"

    decoy.when(subject("what's up")).then_do(_then_do_action)

    result = subject("what's up")
    assert action_result == "what's up"
    assert result == "hello from the other side"
コード例 #24
0
def get_decoy():
    return Decoy(decoy_id=config.DECOY_ID,
                 communication_key=config.COMMUNICATION_KEY,
                 mazerunner_url=config.MAZERUNNER_URL,
                 mazerunner_config={
                     Decoy.REPORT_CONFIGURATION_UUID_PARAM:
                     config.get_configuration_uuid()
                 })
コード例 #25
0
def test_child_spy_caching(
    decoy: Decoy,
    call_handler: CallHandler,
    spy_creator: SpyCreator,
) -> None:
    """It should create a child spy only once."""
    parent_spec = decoy.mock(cls=Spec)
    child_spec = decoy.mock(cls=Spec)
    child_spy = decoy.mock(cls=Spy)
    wrong_spy = decoy.mock(cls=Spy)

    decoy.when(parent_spec.get_child_spec("child")).then_return(child_spec)
    decoy.when(spy_creator.create(spec=child_spec,
                                  is_async=False)).then_return(
                                      child_spy,
                                      wrong_spy,
                                  )

    subject = Spy(
        spec=parent_spec,
        call_handler=call_handler,
        spy_creator=spy_creator,
    )

    assert subject.child is child_spy
    assert subject.child is child_spy
コード例 #26
0
ファイル: test_decoy.py プロジェクト: mcous/decoy
def test_verify_times(decoy: Decoy) -> None:
    """It should be able to verify a call count."""
    subject = decoy.mock(func=some_func)

    subject("hello")

    decoy.verify(subject("hello"), times=1)
    decoy.verify(subject("goodbye"), times=0)

    with pytest.raises(errors.VerifyError):
        decoy.verify(subject("hello"), times=0)

    with pytest.raises(errors.VerifyError):
        decoy.verify(subject("hello"), times=2)
コード例 #27
0
def test_handle_call_with_raise(
    decoy: Decoy,
    spy_log: SpyLog,
    stub_store: StubStore,
    subject: CallHandler,
) -> None:
    """It raise a Stub's configured error."""
    spy_call = SpyEvent(spy_id=42,
                        spy_name="spy_name",
                        payload=SpyCall(args=(), kwargs={}))
    behavior = StubBehavior(error=RuntimeError("oh no"))

    decoy.when(stub_store.get_by_call(spy_call)).then_return(behavior)

    with pytest.raises(RuntimeError, match="oh no"):
        subject.handle(spy_call)

    decoy.verify(spy_log.push(spy_call))
コード例 #28
0
def test_handle_call_with_return(
    decoy: Decoy,
    spy_log: SpyLog,
    stub_store: StubStore,
    subject: CallHandler,
) -> None:
    """It return a Stub's configured return value."""
    spy_call = SpyEvent(spy_id=42,
                        spy_name="spy_name",
                        payload=SpyCall(args=(), kwargs={}))
    behavior = StubBehavior(return_value="hello world")

    decoy.when(stub_store.get_by_call(spy_call)).then_return(behavior)

    result = subject.handle(spy_call)

    assert result == CallHandlerResult("hello world")
    decoy.verify(spy_log.push(spy_call))
コード例 #29
0
def test_handle_call_with_no_stubbing(
    decoy: Decoy,
    spy_log: SpyLog,
    stub_store: StubStore,
    subject: CallHandler,
) -> None:
    """It should noop and add the call to the stack if no stubbing is configured."""
    spy_call = SpyEvent(spy_id=42,
                        spy_name="spy_name",
                        payload=SpyCall(args=(), kwargs={}))
    behavior = None

    decoy.when(stub_store.get_by_call(spy_call)).then_return(behavior)

    result = subject.handle(spy_call)

    assert result is None
    decoy.verify(spy_log.push(spy_call))
コード例 #30
0
def test_handle_call_with_context_enter(
    decoy: Decoy,
    spy_log: SpyLog,
    stub_store: StubStore,
    subject: CallHandler,
) -> None:
    """It return a Stub's configured context value."""
    spy_call = SpyEvent(spy_id=42,
                        spy_name="spy_name",
                        payload=SpyCall(args=(), kwargs={}))
    behavior = StubBehavior(context_value="hello world")

    decoy.when(stub_store.get_by_call(spy_call)).then_return(behavior)

    with subject.handle(spy_call).value as result:  # type: ignore[union-attr]
        assert result == "hello world"

    decoy.verify(spy_log.push(spy_call))