Bifrost icon indicating copy to clipboard operation
Bifrost copied to clipboard

Use dependency injections for test. (Ninject.MockingKernel.Moq)

Open bnordli opened this issue 9 years ago • 6 comments

Just a suggestion to simplify testing

bnordli avatar Jun 22 '15 13:06 bnordli

I know this is super late to be discussing this; but its been a hectic 18 months :)

Anywho. Why would one need to have the IoC container involved when writing specs? I've never had the need to have the IoC there. We write the code without thinking about IoC - but follows the DI principle.

einari avatar Dec 18 '16 09:12 einari

Welcome back! :)

It is certainly debatable, but we have found it to greatly simplify writing specs:

  1. In the vast amount of cases, injections into test subjects are mocks. Using the IoC container for tests reduces the boilerplate for initializing these mocks. Also, you don't need to store references to these mocks, but can use the container to retrieve them. (See for instance https://github.com/dolittle/Bifrost/pull/661/files#diff-409e2a1bc119b802accd8d5e1f1da9a3 for an example of simplification.)
  2. When the test subject constructor changes (because of new or removed injections), you normally would need to go to all instantiations of this class in tests and add/remove this new dependency. When using IoC in tests, the constructor is never referenced, and the new dependency is automatically injected (as a mock).

btw, this has already been accepted into the ProCoSys fork here: https://github.com/ProCoSys/Bifrost/pull/11

bnordli avatar Dec 18 '16 10:12 bnordli

:) Thanks. Its good to be back.

Thanks for the clarification. I think I see and understand the need, but I'm still reluctant to use the IOC for this.

I think it would be better to have something that optimized for developer experience surrounding this.

Let me sleep another fourthnight on it. :) I'll keep the PR here - please don't close it in any way - good for reference and me understanding it all..

einari avatar Dec 27 '16 20:12 einari

What else would you like to use?

It would certainly be possible to write a custom tool for this, but as the project already uses Moq for mocking, and has an implementation for Ninject, both should be familiar to developers, so it sounds reasonable to use an existing framework to do this. (To be fair, there are no direct dependencies from the test themselves to Ninject.)

The possible downsides I can see are

  1. Dependency on yet another framework (but only in tests): Discussed above.
  2. Added time for tests: I haven't made specific measurements, but the ProCoSys project has made this a standard for tests, and I haven't seen any noticeable degradation.
  3. If any dependencies are removed from the tested class, the tests that still include and test for this dependency don't break during compile time. (Without using this, the broken tests would be discovered and fixed/removed earlier.)

bnordli avatar Dec 29 '16 21:12 bnordli

Seems like Ninject.MockingKernel does not support .NET Core (yet). So either we have to wait for it to get updated, or use another DI framework.

bnordli avatar Jan 06 '17 06:01 bnordli

Marked for waiting

einari avatar Feb 25 '17 00:02 einari