1

Articles such as this point out some of the pitfalls of manually instantiating dependencies in UTs, while showing some of the benefits of doing it, instead, with the .NET's dependency container by use of IServiceCollection and IServiceProvider.

While I do understand the pitfalls and the benefits, what about using a base test class where all the mocks are declared and instantiated (manually) - versus registering dependencies with .NET's commonplace approach?

With an abstract base test class, I have the benefit of having the mocks already declared - and ready to use - throughout all my different UT classes - as opposed to the need of having to resolve the dependencies at each UT class using serviceProdiver.GetService (+) the dependencies are still declared and resolved in a single place. Should they need to be changed, it is as simple as doing it with the centralized dependencies registered with IServiceCollection.

Does that make sense ?

1 Answer 1

4

Preconfigured Mocks or base test classes share a similar problem. Your tests can become more complex than what you are testing.

The main benefit of Arrange, Act, Assert is that the whole test is contained in the method. That includes the setup for the test.

When you move the setup out to shared code you add complexity, because not all your tests will want the same setup.

With a shared setup and different requirements I have to figure out how to load the setup that I want for my test, and be sure that it won't change anything that will affect the other tests when I do so.

This can lead to complicated inheritance or setup objects to cater for all possible scenario's. You end up building your own test framework with more code that the class you are testing!

With AAA, I can copy paste the last test I wrote, adjust the arrange and assert sections and have a new self contained test. It doesn't matter that its WET code instead of DRY, it helps.

3
  • Thanks for the reply. Although I understand in general terms what you say, I still have a hard time realizing why providing a "base" mock set - with the ability for every test to overwrite that mock with its own implementarion (as simple as instantiating a new mock over the original) is that much of a problem - considering the fact that the code duplication it prevents is not that easy. I understand the approach in writing UTs is different than that of designing a software component, but still...
    – Veverke
    Commented Apr 2 at 19:54
  • It's not always a problem, its just a downside of the approach you have to balance
    – Ewan
    Commented Apr 2 at 20:26
  • All right. For clarify, I think the answer should emphasize it's a matter of what's the best trade-off for you. Choosing this over that approach will give you X but deprive of Y.
    – Veverke
    Commented Apr 2 at 22:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.