Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using IoC for Unit Testing

How can a IoC Container be used for unit testing? Is it useful to manage mocks in a huge solution (50+ projects) using IoC? Any experiences? Any C# libraries that work well for using it in unit tests?

like image 577
crauscher Avatar asked Sep 23 '09 13:09

crauscher


People also ask

Should I use IoC container?

The most valuable benefit of using an IoC container is that you can have a configuration switch in one place which lets you change between, say, test mode and production mode. For example, suppose you have two versions of your database access classes...

Why do we need IoC container?

IoC ContainerIt manages object creation and it's life-time, and also injects dependencies to the class. The IoC container creates an object of the specified class and also injects all the dependency objects through a constructor, a property or a method at run time and disposes it at the appropriate time.

What is the use of IoC container in C#?

IoC means that one code calls another; DI goes beyond that and implements IoC by using composition. A DI or IoC container needs to instantiate objects (dependencies) and provide them to the application. To do so, it must deal with constructor injection, setter injection, and interface injection.

What is unit test DevOps?

Unit tests execution is one of the key stages of the database DevOps process. It ensures that the changes made by developers to database projects will be verified and all the functionality will work correctly after deployment. To organize DevOps unit testing, you need to have dbForge SQL Tools installed.


2 Answers

Generally speaking, a DI Container should not be necessary for unit testing because unit testing is all about separating responsibilities.

Consider a class that uses Constructor Injection

public MyClass(IMyDependency dep) { } 

In your entire application, it may be that there's a huge dependency graph hidden behind IMyDependency, but in a unit test, you flatten it all down to a single Test Double.

You can use dynamic mocks like Moq or RhinoMocks to generate the Test Double, but it is not required.

var dep = new Mock<IMyDependency>().Object; var sut = new MyClass(dep); 

In some cases, an auto-mocking container can be nice to have, but you don't need to use the same DI Container that the production application uses.

like image 161
Mark Seemann Avatar answered Oct 10 '22 11:10

Mark Seemann


I often use an IoC container in my tests. Granted, they are not "unit tests" in the pure sense. IMO They are more BDDish and facilitate refactoring. Tests are there to give you confidence to refactor. Poorly written tests can be like pouring cement into your code.

Consider the following:

[TestFixture] public class ImageGalleryFixture : ContainerWiredFixture {     [Test]     public void Should_save_image()     {         container.ConfigureMockFor<IFileRepository>()             .Setup(r => r.Create(It.IsAny<IFile>()))             .Verifiable();          AddToGallery(new RequestWithRealFile());          container.VerifyMockFor<IFileRepository>();     }      private void AddToGallery(AddBusinessImage request)     {         container.Resolve<BusinessPublisher>().Consume(request);     } } 

There are several things that happen when adding an image to the gallery. The image is resized, a thumbnail is generated, and the files are stored on AmazonS3. By using a container I can more easily isolate just the behavior I want to test, which in this case is the persisting part.

An auto-mocking container extension comes in handy when using this technique: http://www.agileatwork.com/auto-mocking-unity-container-extension/

like image 24
Mike Valenty Avatar answered Oct 10 '22 10:10

Mike Valenty