Пример #1
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
Пример #2
0
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`>"
Пример #3
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()
Пример #4
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
Пример #5
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
Пример #6
0
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)
Пример #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_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
Пример #9
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
Пример #10
0
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"))
Пример #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_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)
Пример #13
0
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"))
Пример #14
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)
Пример #15
0
def test_verify(decoy: Decoy) -> None:
    """It should be able to configure a verification with a rehearsal."""
    subject = decoy.mock(func=some_func)

    subject("hello")

    decoy.verify(subject("hello"))
    decoy.verify(subject(val="hello"))

    with pytest.raises(errors.VerifyError):
        decoy.verify(subject("goodbye"))
Пример #16
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")
Пример #17
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
Пример #18
0
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)
Пример #19
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"))
Пример #20
0
def test_verify_call_list(decoy: Decoy) -> None:
    """It should be able to verify multiple calls."""
    subject_1 = decoy.mock(cls=SomeClass)
    subject_2 = decoy.mock(cls=SomeNestedClass)

    subject_1.foo("hello")
    subject_2.child.bar(1, 2.0, "3")
    subject_1.foo("goodbye")

    decoy.verify(
        subject_1.foo("hello"),
        subject_2.child.bar(1, 2.0, "3"),
        subject_1.foo("goodbye"),
    )

    with pytest.raises(errors.VerifyError):
        decoy.verify(
            subject_1.foo("hello"),
            subject_1.foo("goodbye"),
            subject_2.child.bar(1, 2.0, "3"),
        )
Пример #21
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
Пример #22
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
Пример #23
0
def test_generator_context_manager_mock(decoy: Decoy) -> None:
    """It should be able to mock a generator-based context manager."""
    class _ValueReader:
        def get_value(self) -> int:
            ...

    class _ValueReaderLoader:
        @contextlib.contextmanager
        def get_value_reader(self) -> Iterator[_ValueReader]:
            ...

    value_reader_loader = decoy.mock(cls=_ValueReaderLoader)
    value_reader = decoy.mock(cls=_ValueReader)

    decoy.when(
        value_reader_loader.get_value_reader()).then_enter_with(value_reader)
    decoy.when(value_reader.get_value()).then_return(42)

    with value_reader_loader.get_value_reader() as subject:
        result = subject.get_value()

    assert result == 42
Пример #24
0
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)
Пример #25
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
Пример #26
0
async def test_async_generator_context_manager_mock(decoy: Decoy) -> None:
    """It should be able to mock a generator-based context manager."""
    class _ValueReader:
        def get_value(self) -> int:
            ...

    class _ValueReaderLoader:
        @contextlib.asynccontextmanager
        async def get_value_reader(self) -> AsyncIterator[_ValueReader]:
            raise NotImplementedError()
            yield

    value_reader_loader = decoy.mock(cls=_ValueReaderLoader)
    value_reader = decoy.mock(cls=_ValueReader)

    decoy.when(
        value_reader_loader.get_value_reader()).then_enter_with(value_reader)
    decoy.when(value_reader.get_value()).then_return(42)

    async with value_reader_loader.get_value_reader() as subject:
        result = subject.get_value()

    assert result == 42
Пример #27
0
async def test_spy_async_context_manager(
    decoy: Decoy,
    call_handler: CallHandler,
    spy_creator: SpyCreator,
    spec: Spec,
) -> None:
    """It should be usable in an `async with` statement."""
    enter_spec = decoy.mock(cls=Spec)
    exit_spec = decoy.mock(cls=Spec)
    enter_spy = decoy.mock(cls=AsyncSpy)
    exit_spy = decoy.mock(cls=AsyncSpy)
    error = RuntimeError("oh no")

    decoy.when(spec.get_name()).then_return("spy_name")
    decoy.when(spec.get_child_spec("__aenter__")).then_return(enter_spec)
    decoy.when(spec.get_child_spec("__aexit__")).then_return(exit_spec)
    decoy.when(spy_creator.create(spec=enter_spec,
                                  is_async=True)).then_return(enter_spy)
    decoy.when(spy_creator.create(spec=exit_spec,
                                  is_async=True)).then_return(exit_spy)
    decoy.when(await enter_spy()).then_return(42)

    subject = Spy(spec=spec,
                  call_handler=call_handler,
                  spy_creator=spy_creator)
    tb = None

    try:
        async with subject as result:
            assert result == 42
            raise error
    except RuntimeError:
        tb = sys.exc_info()[2]
        pass

    decoy.verify(await exit_spy(RuntimeError, error, tb))
Пример #28
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
Пример #29
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"
Пример #30
0
def test_create_spy(decoy: Decoy, call_handler: CallHandler) -> None:
    """It should get default configurations from the spec."""
    spec = decoy.mock(cls=Spec)
    sig = inspect.signature(some_func)

    decoy.when(spec.get_full_name()).then_return("hello.world")
    decoy.when(spec.get_signature()).then_return(sig)
    decoy.when(spec.get_class_type()).then_return(SomeClass)

    subject = SpyCreator(call_handler=call_handler)
    result = subject.create(spec=spec, name="foo")

    assert isinstance(result, Spy)
    assert isinstance(result, SomeClass)
    assert inspect.signature(result) == sig
    assert repr(result) == "<Decoy mock `hello.world`>"