def test_resolve_returns_the_latest_registration_for_a_service(): container = Container() container.register(MessageWriter, StdoutMessageWriter) container.register(MessageWriter, TmpFileMessageWriter, path="my-file") expect(container.resolve(MessageWriter)).to(be_a(TmpFileMessageWriter))
def test_defaults_are_superseded_by_context(): container = Container() container.register(Dep) container.register(Client) client = container.resolve(Client, b=5) expect(client.b).to(equal(5))
def test_can_create_instance_with_defaulted_kwarg(): container = Container() container.register(Dep) container.register(Client) client = container.resolve(Client) expect(client.b).to(equal(10))
def test_resolves_instances_with_prototype_scope(): container = Container() container.register(MessageWriter, StdoutMessageWriter, scope=Scope.transient) mw1 = container.resolve(MessageWriter) mw2 = container.resolve(MessageWriter) expect(mw1).not_to(equal(mw2))
def test_resolves_instances_with_singleton_scope(): container = Container() container.register(MessageWriter, StdoutMessageWriter, scope=Scope.singleton) mw1 = container.resolve(MessageWriter) mw2 = container.resolve(MessageWriter) expect(mw1).to(equal(mw2))
def test_can_provide_arguments_to_resolve_having_dependencies(): container = Container() container.register(StdoutMessageWriter, StdoutMessageWriter) container.register(MessageWriter, WrappingMessageWriter) instance = container.resolve(MessageWriter, context="bar") expect(instance.context).to(equal("bar"))
def test_defaults_are_superseded_by_registrations(): container = Container() container.register(Dep) container.register(Client) container.register(int, lambda: 3) client = container.resolve(Client) expect(client.b).to(equal(3))
def test_resolve_all_returns_all_registrations_in_order(): container = Container() container.register(MessageWriter, StdoutMessageWriter) container.register(MessageWriter, TmpFileMessageWriter, path="my-file") [first, second] = container.resolve_all(MessageWriter) expect(first).to(be_a(StdoutMessageWriter)) expect(second).to(be_a(TmpFileMessageWriter))
def test_can_provide_arguments_to_registrations(): container = Container() container.register(MessageWriter, FancyDbMessageWriter, cstr=lambda: "Hello world") writer = container.resolve(MessageWriter) expect(writer).to(be_a(FancyDbMessageWriter)) expect(writer.connection_string).to(equal("Hello world"))
def test_dependencies_are_injected(): container = Container() container.register(MessageWriter, StdoutMessageWriter) container.register(MessageSpeaker, HelloWorldSpeaker) speaker = container.resolve(MessageSpeaker) expect(speaker).to(be_a(HelloWorldSpeaker)) expect(speaker.writer).to(be_a(StdoutMessageWriter))
def test_can_register_with_a_custom_factory(): container = Container() container.register(MessageWriter, lambda: "win") container.register(MessageSpeaker, HelloWorldSpeaker) speaker = container.resolve(MessageSpeaker) expect(speaker).to(be_a(HelloWorldSpeaker)) expect(speaker.writer).to(equal("win"))
def test_registering_an_instance_as_factory_is_exception(): """ Concrete registrations need to be a constructable type or there's no key we can use for resolution. """ container = Container() writer = MessageWriter() with pytest.raises(InvalidRegistrationException): container.register(MessageWriter, writer)
def test_resolves_instances(): """ No scope specified should work the way transient scope works """ container = Container() container.register(MessageWriter, StdoutMessageWriter) mw1 = container.resolve(MessageWriter) mw2 = container.resolve(MessageWriter) expect(mw1).not_to(equal(mw2))
def test_registering_a_callable_as_concrete_is_exception(): """ Likewise, if we register an arbitrary callable, there's no key by which we can later resolve, so we reject the registration """ container = Container() with pytest.raises(InvalidRegistrationException): container.register(lambda: "oops")
def test_can_provide_typed_arguments_to_resolve(): container = Container() container.register(MessageWriter, TmpFileMessageWriter) container.register(TmpFileMessageWriter) container.register(HelloWorldSpeaker) tmpfile = NamedTemporaryFile() writer = container.resolve(MessageWriter, path=tmpfile.name) speaker = container.resolve(HelloWorldSpeaker, writer=writer) speaker.speak() tmpfile.seek(0) expect(tmpfile.read().decode()).to(equal("Hello World"))
def test_can_resolve_a_chain_of_dependencies(): """ In this test we construct a chain of responsibility that's managed by the container. When we invoke the chain each element of the chain is provided with its onward dependencies. """ spy = [] container = Container() container.register(Filter, NullFilter, spy=spy) container.register(Filter, Is_C, spy=spy) container.register(Filter, Is_B, spy=spy) container.register(Filter, Is_A, spy=spy) filter = container.resolve(Filter) filter.match("D") expect(spy).to(equal(["is_a", "is_b", "is_c", "null"]))
def test_can_resolve_a_list_of_dependencies(): """ In this test we create a composite MessageSpeaker that depends on a list of MessageWriters. When we resolve the speaker, it should be provided with a list of all the registered writers. """ class BroadcastSpeaker: def __init__(self, writers: List[MessageWriter]) -> None: self.writers = writers container = Container() container.register(MessageWriter, StdoutMessageWriter) container.register(MessageWriter, TmpFileMessageWriter, path="my-file") container.register(MessageSpeaker, BroadcastSpeaker) instance = container.resolve(MessageSpeaker) expect(instance.writers).to(have_len(2))
def test_can_provide_arguments_to_resolve(): container = Container() container.register(MessageWriter, TmpFileMessageWriter) instance = container.resolve(MessageWriter, path="foo") expect(instance.path).to(equal("foo"))
def test_can_register_an_instance(): container = Container() writer = TmpFileMessageWriter("my-file") container.register(MessageWriter, instance=writer) expect(container.resolve(MessageWriter)).to(equal(writer))
import pkgutil import unittest from importlib import import_module from punq import Container from shared import set_container from shared.querysets.base import QuerySet from shared.querysets.memory import MemoryQuerySet from shared.querysets.users import UserQuerySet, UserMemoryQuerySet from shared.services import UserService container = Container() container.register(QuerySet, instance=MemoryQuerySet) container.register(UserQuerySet, factory=UserMemoryQuerySet) container.register(UserService) set_container(container) def get_submodules(package): for importer, modname, ispkg in pkgutil.iter_modules(package.__path__): submodule = importer.find_module(modname).load_module(modname) yield submodule if ispkg: yield from get_submodules( importer.find_module(submodule.__spec__.name, ).load_module( submodule.__spec__.name, ), )
def test_can_register_a_concrete_type(): container = Container() container.register(StdoutMessageWriter) expect(container.resolve(StdoutMessageWriter)).to( be_a(StdoutMessageWriter))
def test_missing_dependencies_raise_exception(): container = Container() container.register(MessageSpeaker, HelloWorldSpeaker) with pytest.raises(MissingDependencyException): container.resolve(MessageSpeaker)
def test_can_create_instance_with_no_dependencies(): container = Container() container.register(MessageWriter, StdoutMessageWriter) expect(container.resolve(MessageWriter)).to(be_a(StdoutMessageWriter))
def test_can_use_a_string_key(): container = Container() container.register("foo", instance=1) assert container.resolve("foo") == 1
def test_can_instatiate_with_no_dependencies(): container = Container() expect(container.instantiate(StdoutMessageWriter)).to(be_a(StdoutMessageWriter))