Usually when using dependency injection, unit (and other) tests are responsible for creating/mocking dependencies of the system-under-test and injecting them.
However, sometimes the test itself has dependencies, or needs to inject dependencies into the SUT that it can't itself create. For example, when testing classes which interact with a database, the test needs to know connection strings and catalog names etc., which can't be hard-coded since they aren't necessarily the same for everybody running the test.
So, how would you recommend that a test find out these settings? Do some xUnit-style test frameworks provide a way to give dependencies to a test fixture? Should the test class have static properties you populate before running all the tests? Should the test ignore DI practices and just go and get the dependencies from some global place? Other suggestions?
Every time you make a change to your constructor, you have to revisit all test cases and rewrite them. It does not matter whether or not that new dependency is part of your test. Wouldn’t it be nice to be able to use dependency injection in unit tests? Well this is in fact possible with Autofixture.
Dependency Injection is a way of injecting the dependencies into your class. Your class declares it’s dependencies (e.g. via a constructor parameter) and whoever is using your class can provide those dependencies. This way we don’t hard-code dependencies into our classes and our codebase is a lot more flexible.
Well this is in fact possible with Autofixture. Autofixture is a testing framework created by Mark Seemann, author of “Dependency Injection: Principles, Practices, Patterns”. He is was also part of the team that developed F#! This guy is crazy smart, and really interesting to listen to.
If a test class constructor, a test method, or a lifecycle method accepts a parameter, the parameter must be resolved at runtime by a registered ParameterResolver. You can inject as many parameters as you want in any order you want them to be.
There's a principle for fully automated tests: you should be able to pull down all the source code from the source control repository and simply run the tests.
Given that the environment (machine) has the correct installation base (i.e. compiler, test framework, database engine if relevant, etc.) the tests are responsible for setting up their Fixture before executing the test cases.
That means that for databases, the tests should
If, for some reason you can't do that, the only thing you can really do is to have a configuration file in your source control system that contains machine-specific entries for all machines in your testing invironment; e.g. for the machine Tst1 the connection string is one value, but for Tst2 it's another.
This can get ugly really quickly, so it's much easier to have the tests be responsible for Fixture Setup and Teardown, because that means that they can simply use hard-coded values, or values generated on the spot.
This really has nothing to do with DI...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With