unit-testing Dependency Injection Constructor Injection


Example

Constructor injection is the safest way of injecting dependencies that a whole class depends upon. Such dependencies are often referred to as invariants, since an instance of the class cannot be created without supplying them. By requiring the dependency to be injected at construction, it is guaranteed that an object cannot be created in an inconsistent state.

Consider a class that needs to write to a log file in error conditions. It has a dependency on a ILogger, which can be injected and used when necessary.

public class RecordProcessor
{
    readonly private ILogger _logger;

    public RecordProcessor(ILogger logger)
    {
        _logger = logger;
    }

    public void DoSomeProcessing() {
        // ...
        _logger.Log("Complete");
    }
}

Sometimes while writing tests you may note that constructor requires more dependencies than it is actually needed for a case being tested. The more such tests you have the more likely it is that your class breaks Single Responsibility Principle (SRP). That is why it it is not a very good practice to define the default behavior for all mocks of injected dependencies at test class initialization phase as it can mask the potential warning signal.

The unittest for this would look like the following:

[Test]
public void RecordProcessor_DependencyInjectionExample()
{
    ILogger logger = new FakeLoggerImpl(); //or create a mock by a mocking Framework
    
    var sut = new RecordProcessor(logger); //initialize with fake impl in testcode

    Assert.IsTrue(logger.HasCalledExpectedMethod());
}