Пример #1
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,
                ),
            ), ))
Пример #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
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
Пример #4
0
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()
Пример #5
0
def test_verify(
    decoy: Decoy,
    spy_log: SpyLog,
    verifier: Verifier,
    subject: DecoyCore,
) -> None:
    """It should be able to verify a call."""
    spy_id = 42
    rehearsal = VerifyRehearsal(spy_id=spy_id,
                                spy_name="my_spy",
                                payload=SpyCall(args=(), kwargs={}))
    call = SpyEvent(spy_id=spy_id,
                    spy_name="my_spy",
                    payload=SpyCall(args=(), kwargs={}))

    decoy.when(
        spy_log.consume_verify_rehearsals(
            count=1, ignore_extra_args=False)).then_return([rehearsal])

    decoy.when(spy_log.get_calls_to_verify([spy_id])).then_return([call])

    subject.verify("__rehearsal__", times=None, ignore_extra_args=False)

    decoy.verify(
        verifier.verify(rehearsals=[rehearsal], calls=[call], times=None))
Пример #6
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),
        ),
    )
Пример #7
0
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
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
Пример #9
0
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
Пример #10
0
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
Пример #11
0
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
Пример #12
0
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
Пример #13
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)
Пример #14
0
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
Пример #15
0
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")
Пример #16
0
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
Пример #17
0
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
Пример #18
0
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"
Пример #19
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
Пример #20
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))
Пример #21
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))
Пример #22
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))
Пример #23
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))
Пример #24
0
class DecoyTestCase(unittest.TestCase):
    """Decoy test case using unittest."""
    def setUp(self) -> None:
        """Set up before each test."""
        self.decoy = Decoy()

    def tearDown(self) -> None:
        """Clean up after each test."""
        self.decoy.reset()

    def test_when(self) -> None:
        """Test that self.decoy.when works."""
        mock = self.decoy.mock(cls=SomeClass)
        self.decoy.when(mock.foo("hello")).then_return("world")
        assert mock.foo("hello") == "world"

    def test_verify(self) -> None:
        """Test that self.decoy.verify works."""
        mock = self.decoy.mock(cls=SomeClass)
        mock.foo("hello")
        self.decoy.verify(mock.foo("hello"))
Пример #25
0
def test_when_ignore_extra_args(
    decoy: Decoy,
    spy_log: SpyLog,
    stub_store: StubStore,
    subject: DecoyCore,
) -> None:
    """It should be able to register a new stubbing."""
    rehearsal = WhenRehearsal(spy_id=1,
                              spy_name="my_spy",
                              payload=SpyCall(args=(), kwargs={}))
    decoy.when(spy_log.consume_when_rehearsal(
        ignore_extra_args=True)).then_return(rehearsal)

    result = subject.when("__rehearsal__", ignore_extra_args=True)
    result.then_return("hello")

    decoy.verify(
        stub_store.add(
            rehearsal=rehearsal,
            behavior=StubBehavior(return_value="hello", once=False),
        ))
Пример #26
0
def test_handle_call_with_action(
    decoy: Decoy,
    spy_log: SpyLog,
    stub_store: StubStore,
    subject: CallHandler,
) -> None:
    """It should trigger a stub's configured action."""
    action = decoy.mock()
    spy_call = SpyEvent(
        spy_id=42,
        spy_name="spy_name",
        payload=SpyCall(args=(1, ), kwargs={"foo": "bar"}),
    )
    behavior = StubBehavior(action=action)

    decoy.when(stub_store.get_by_call(spy_call)).then_return(behavior)
    decoy.when(action(1, foo="bar")).then_return("hello world")

    result = subject.handle(spy_call)

    assert result == CallHandlerResult("hello world")
Пример #27
0
def test_reset(
    decoy: Decoy,
    spy_log: SpyLog,
    stub_store: StubStore,
    warning_checker: WarningChecker,
    subject: DecoyCore,
) -> None:
    """It should reset the stores."""
    call = SpyEvent(spy_id=1,
                    spy_name="my_spy",
                    payload=SpyCall(args=(), kwargs={}))

    decoy.when(spy_log.get_all()).then_return([call])

    subject.reset()

    decoy.verify(
        warning_checker.check([call]),
        spy_log.clear(),
        stub_store.clear(),
    )
Пример #28
0
def test_spy_calls(
    decoy: Decoy,
    call_handler: CallHandler,
    spy_creator: SpyCreator,
    spec: Spec,
) -> None:
    """It should send any calls to the call handler."""
    subject = Spy(spec=spec,
                  call_handler=call_handler,
                  spy_creator=spy_creator)

    decoy.when(spec.get_name()).then_return("spy_name")
    decoy.when(spec.bind_args(1, 2, three=3)).then_return(
        BoundArgs(args=(1, 2, 3), kwargs={}))
    decoy.when(
        call_handler.handle(
            SpyEvent(
                spy_id=id(subject),
                spy_name="spy_name",
                payload=SpyCall(args=(1, 2, 3), kwargs={}),
            ))).then_return(CallHandlerResult(42))

    result = subject(1, 2, three=3)

    assert result == 42
Пример #29
0
def test_child_spy(
    decoy: Decoy,
    call_handler: CallHandler,
    spy_creator: SpyCreator,
) -> None:
    """It should create a child spy."""
    parent_spec = decoy.mock(cls=Spec)
    child_spec = decoy.mock(cls=Spec)
    child_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)

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

    result = subject.child
    assert result is child_spy
Пример #30
0
def test_handle_prop_get_with_action(
    decoy: Decoy,
    spy_log: SpyLog,
    stub_store: StubStore,
    subject: CallHandler,
) -> None:
    """It should trigger a prop get stub's configured action."""
    action = decoy.mock()
    spy_call = SpyEvent(
        spy_id=42,
        spy_name="spy_name",
        payload=SpyPropAccess(prop_name="prop",
                              access_type=PropAccessType.GET),
    )
    behavior = StubBehavior(action=action)

    decoy.when(stub_store.get_by_call(spy_call)).then_return(behavior)
    decoy.when(action()).then_return("hello world")

    result = subject.handle(spy_call)

    assert result == CallHandlerResult("hello world")