Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you test dependency injection?

Dependency injection helps you unit test your code pretty well. But how do we test if the right dependencies are injected finally at run time ?? For example I have a service class which takes in a list of service validators. Since the list of validators is injected by a DI container, how do we make sure that the right validators are injected ?? What if some developer mistakenly removes a validator from the list. Even if we do write tests on the depen dency injection, we can't assert on all dependencies without breaking encapsulation. The only way is an integration test which asserts on the validation behaviour of the service. If the service behaviour is complicated, then it becomes difficult to write integration tests. Any ideas ??

like image 206
uttamkini Avatar asked Aug 06 '11 15:08

uttamkini


1 Answers

To paraphrase your question:

I have tested the individual components of my application and they all work, but how do I know the application as a whole works?

Good News

Consider how good a position you are in, compared to being in a position to ask:

I've written all this code now, how do I know if the application works?

You found and removed bugs in unit test. Coding in a dependency injection style made dependencies clear and removed reliance on global variables. These techniques in themselves mean you would have less bugs, and particularily less bugs that only show themselves when the entire application is put together.

Test Bigger

Now, to move on to answer your question, you could write an automated test to assert that a particular validator is returned by your dependency injection container. Better yet, I favour writting tests that:-

  • Ask the DI container for an object (behind which lies a graph of collaborating objects e.g. a list of validators)
  • Ask the object to perform it's function (validate this data)
  • Assert the result (e.g. validation error)

You might want to replace certain objects that access the database, the current server time, a web service, etc with a test double. This is easy because you are using dependency injection.

Unless a class is particularly troublesome, I prefer to test at this level because it allows more tests to survive refactoring. Classes with a cyclomatic complexity of 1 do not require stand-alone testing if exercised as part of a larger test. Classes with higher cyclomatic complexity may.

Lots of tests, but does it work?

Even then, you may be wondering, But does the whole thing work?

To finally answer this question, you need to test the application in its final form. For a web application, this means deploying it on a proper server with a proper database and the real firewall, etc. Then you can manually test or test with something like Selenium.

Failures to inject the correct dependencies would result in a catastrophic error in whatever feature the injected component is meant to do. It is not necessary to test every combination but lightly touch upon each component.

like image 126
WW. Avatar answered Oct 07 '22 12:10

WW.