Is unit testing required for root composition?

I tried to find the answer, but it seems that it was not discussed directly. I have the root of the composition of my application, where I create a DI container and register everything there, and then allow the necessary top-level classes that get all the dependencies. As all this happens inside, it becomes difficult to unit test the root of the composition. You can do virtual methods, protected fields, etc., but I'm not a big fan of introducing such things to be able to unit test. Other classes do not have big problems, since they all use constructor injection. So the question is, does it make sense to test the root of the composition in general? It has additional logic, but not so much, and in most cases, any failures appear during application launch. Some code that I have:

public void Initialize(/*Some configuration parameters here*/) { m_Container = new UnityContainer(); /*Regestering dependencies*/ m_Distributor = m_Container.Resolve<ISimpleFeedMessageDistributor>(); } public void Start() { if (m_Distributor == null) { throw new ApplicationException("Initialize should be called before start"); } m_Distributor.Start(); } public void Close() { if (m_Distributor != null) { m_Distributor.Close(); } } 
+7
c # dependency-injection compositionroot
source share
1 answer

Does it make sense to test the root of the composition in general?

Do you want to know if your application is written correctly? You are probably doing this and why you are writing tests. For the same reason, you should check your root directory.

However, these tests specifically target the correct wiring of the system. You do not want to check the correct functioning of one class, as this is already covered by some unit test. Also, you do not want to check whether classes are called other classes in the correct order, because what you want to test in your usual integration tests (call the MVC controller and see if the call ends in the database is an example of such an integration test).

Here are some things you should probably check out:

  • So that all top-level classes can be resolved. This does not allow you to click all screens in the application to find out if the wiring is installed correctly.
  • These components depend only on services with an equal or longer service life. When components depend on another component that is configured for a shorter lifetime, this component will “contribute” to the lifetime of this dependency, which often leads to errors that are difficult to reproduce and correct. It is important to check for such problems. This type of error is also known as lifestyle mismatch or implicit attitude.
  • These decorators and other interception mechanisms, which are crucial to the correctness of the application, are applied correctly. Decorators can, for example, add problems with cross-environments, such as transaction processing, security and caching, and it is important that these problems are performed in the correct order (for example, a security check must be performed before requesting the cache), but it can be difficult to verify this. using a regular integration test.

To be able to do this, you need to have a verifiable DI configuration .

Note that not everyone shares this opinion. However, my experience is that validating your configuration is very valuable.

Thus, testing these things can be difficult with some IoC containers, while another IoC container has options to help you with this (but Unity, unfortunately, does not have most of these features).

Some containers have some kind of validation method that you can call that will validate the configuration. What “verification” means is different for each library. A simple injector, for example (I’m the lead developer for Simple Injector), has a Verify method that will simply GetInstance over all registrations and call GetInstance for each of them to ensure that every instance can be created. I always advise the users you call Verify in your root directory whenever possible. This is not always possible, for example, because when the configuration becomes large, a call to Verify may cause the application to start too slowly. But still, this is a good starting point and can eliminate the pain. If this takes a long time, you can always transfer the call to an automatic test.

And for a simple injector, this is just the beginning. A simple injector contains “Diagnostic Services” , which checks the container for common incorrect configurations, for example, the previously declared “lifestyle mismatch”.

So, you should absolutely want to test, but I'm not sure whether these tests should be called "unit tests", although I manage to run these tests in isolation (without having to get into the database or web service).

+8
source share

All Articles