Unit Testing the Dependency Injection in C#

What is Dependency Injection?

Dependency injection is a design pattern that promotes loose coupling between classes by allowing dependencies to be provided from external sources. Instead of a class creating its own dependencies, those dependencies are passed to the class through its constructor, properties, or method parameters. This allows for easier testing, as dependencies can be easily mocked or stubbed during unit testing.

How to Implement Dependency Injection in C

To implement dependency injection in C#, we need to follow a few steps:

  1. Identify the dependencies of the class: The first step is to identify the dependencies that the class requires to function properly. These dependencies can be other classes, interfaces, or services.

  2. Create interfaces for the dependencies: Once the dependencies are identified, it is recommended to create interfaces for them. This allows for easier mocking and stubbing during unit testing.

  3. Modify the class to accept dependencies through its constructor: The next step is to modify the class to accept its dependencies through its constructor. This is known as constructor injection. By doing this, the class becomes more flexible and easier to test.

  4. Use a dependency injection container: To manage the creation and resolution of dependencies, we can use a dependency injection container. A container is responsible for creating instances of classes and resolving their dependencies.

Example: Unit Testing a Class with Dependency Injection

Let’s consider an example where we have a MainClass that depends on a logger and a database. Here’s how we can refactor the MainClass to follow the explicit dependencies principle:

public class MainClass : IMainClass  
{
    private readonly ILogger logger;
    private readonly IDatabase db;

    public MainClass(ILogger logger, IDatabase db) 
    {
        this.logger = logger;  
        this.db = db;
    }

    public void AddDetails(Data data) 
    {
        // do some business operations 
        db.Add(data);
        logger.Information("added");
    }
}

In the above code, we have modified the MainClass to accept its dependencies (ILogger and IDatabase) through its constructor.

To test the MainClass, we need to mock the necessary dependencies. Here’s an example of how we can write a unit test for the AddDetails method:

[TestClass]
public class MainClassTests 
{    
    [TestMethod]
    public void Should_AddDetails_To_Database() 
    {
        // Arrange
        var mockDb = new Mock<IDatabase>();
        var data = new Data();
        var mainClass = new MainClass(Mock.Of<ILogger>(), mockDb.Object);

        // Act
        mainClass.AddDetails(data);

        // Assert    
        mockDb.Verify(_ => _.Add(data), Times.Once);
    }
}

In the above test, we create a mock object for the IDatabase dependency and pass it to the MainClass constructor along with a mocked ILogger object. We then call the AddDetails method and assert that the Add method of the IDatabase dependency is called once with the correct data.

Conclusion

In this article, we have explored how to unit test code that uses dependency injection in C#. By following the steps outlined above, we can effectively manage dependencies and write testable code. The use of dependency injection allows for easier mocking and stubbing of dependencies during unit testing, resulting in more reliable and maintainable code.

Categories C#

Related Posts

How to Set Column Header Text for a Specific Column in DataGridView in C#

Prerequisites To follow along with this tutorial, you will need a basic understanding of C# programming and the Windows Forms framework. Step-by-Step Guide Step 1: Create a new Windows Forms application First, let’s create a new Windows Forms application in Visual Studio. Open Visual Studio and select “Create a new project”. Choose the “Windows Forms ...

Read more

How to Create an Excel (.XLS and .XLSX) File in C# without Installing Microsoft Office

If you’re a C# developer looking to create Excel files without the need to install Microsoft Office, you’re in luck! There are several libraries available that can help you achieve this task easily and efficiently. In this article, we will explore two popular libraries, ExcelLibrary and EPPlus, and discuss how to use them to create ...

Read more

Why would one use Task over ValueTask in C#?

When working with asynchronous programming in C#, developers have the option to use either Task<T> or ValueTask<T> to represent the result of an asynchronous operation. Both types provide similar functionality, but there are certain scenarios where using Task<T> is preferred over ValueTask<T>. In this article, we will explore the reasons why one would choose Task<T> ...

Read more

Better Way to Cast Object to Int in C#

Have you ever encountered a situation where you needed to cast an object to an integer in your C# code? If so, you may have wondered what the best approach is to achieve this. In this article, we will explore different methods to cast an object to an int in C# and discuss the scenarios ...

Read more

Leave a Comment