reagento / dishka

Cute DI framework with agreeable API and everything you need
https://dishka.readthedocs.io
Apache License 2.0
355 stars 39 forks source link

Dishka testing #220

Closed Forceres closed 2 weeks ago

Forceres commented 3 weeks ago

In docs we have a page with testing example. But, actually, in real tests we have a lot of dependencies and we need to make a lot of mocks, so it is not convenient to re-write fully mocked provider (also sometimes we need to mock some methods in certain tests and have it unmocked in others). Maybe something like dependency_override method could be implemented or there are some other best practices for testing with dishka (mocking dishka, support FromDishka in pytest)?

Tishka17 commented 3 weeks ago

You do not need to change whole provider. Just add new one overriding something. You need to create new container, but you can still use old providers.

But I want to draw your attention to the types of tests you are writing: you do not need container other than pytest in unit tests

Forceres commented 3 weeks ago

You do not need to change whole provider. Just add new one overriding something. You need to create new container, but you can still use old providers.

But I want to draw your attention to the types of tests you are writing: you do not need container other than pytest in unit tests

Our providers can be big and have a lot of dependencies, so it is not cool to add new class declaration with overriding some methods, what do you mean by "you do not need container other than pytest in unit tests"? It could be cool to have a container that can be mocked in runtime (for tests only) and then have DI from that container in pytest automatically

Tishka17 commented 3 weeks ago

so it is not cool to add new class declaration with overriding some methods

Sorry, I did not get the problem.

Let's suppose you have production my_prod_provider=MyProdProvider() which provides a lot of things and, for example, DatabaseGateway among them. If you want to mock only that gateway, keeping all other factories the same as in prod, you jsut create a new provider and use both of them

class MockProvider(Provider):
   db = provide(MockDbGateway, provides=DatabaseGateway)

test_cotnainer = make_container(my_prod_provider, MockProvider())

By saying "you do not need container other than pytest in unit tests" I mean that dishka container is a thing which you use to integrate all parts of an application together. If you are doing a unit test for some class you can pass mocked dependencies directly. It is easier and more flexible. You do not need hierarchy of objects here - leave it for integration tests.

But, you can use pytest fixtures here as it bases on names and you can have lots of mocked versions and use them in different tests in different cobinations.

Forceres commented 3 weeks ago

so it is not cool to add new class declaration with overriding some methods

Sorry, I did not get the problem.

Let's suppose you have production my_prod_provider=MyProdProvider() which provides a lot of things and, for example, DatabaseGateway among them. If you want to mock only that gateway, keeping all other factories the same as in prod, you jsut create a new provider and use both of them

class MockProvider(Provider):
   db = provide(MockDbGateway, provides=DatabaseGateway)

test_cotnainer = make_container(my_prod_provider, MockProvider())

By saying "you do not need container other than pytest in unit tests" I mean that dishka container is a thing which you use to integrate all parts of an application together. If you are doing a unit test for some class you can pass mocked dependencies directly. It is easier and more flexible. You do not need hierarchy of objects here - leave it for integration tests.

But, you can use pytest fixtures here as it bases on names and you can have lots of mocked versions and use them in different tests in different cobinations.

Is pytest_mock working with dishka?

Tishka17 commented 3 weeks ago

I have no idea what is the purpose of pytest-mock. I recommend using unittest.mock and avoid monkey patching

Tishka17 commented 2 weeks ago

Can I help with anything else related to the topic of the issue?

Forceres commented 2 weeks ago

Can I help with anything else related to the topic of the issue?

That's it, can it be moved to discussions?