Search code examples
c#unit-testingdependency-injectionlanguage-agnosticdependencies

Is there a compelling reason to use DI with a module/class with no dependencies in a unit test?


Dependency injection can prove very useful for testing modules with dependencies. This isn't about those.


Say there is some concrete implementation,

public class DoesSomething : IDoesSomething 
{
    public int DoesImportant(int x, int y) 
    { 
        // perform some operation 
    }
}

that implements this,

public interface IDoesSomething
{
    int DoesImportant(int x, int y); 
}

In a unit test, you can obviously new up the test,

[TestMethod]
public void DoesSomething_CanDoDoesImportant()
{ 
    int expected = 42; 

    IDoesSomething foo = new DoesSomething(); 
    int actual = foo.DoesImportant(21, 2); 

    Assert.AreEqual(expected, actual); 
}

or use DI (Autofac here, but shouldn't matter for principle of question),

[TestMethod]
public void DoesSomething_CanDoDoesImportant()
{
    var builder = new ContainerBuilder();
    builder.RegisterType<DoesSomething>().As<IDoesSomething>();
    var container = builder.Build();

    int expected = 42;
    IDoesSomething foo = container.Resolve<IDoesSomething>();
    int actual = foo.DoesImportant(21, 2);

    Assert.AreEqual(expected, actual);
}

Given such a standalone module with no dependencies, is there a compelling reason to inject an IDoesSomething into the test? Or, is there a compelling reason to not inject an IDoesSomething?


Solution

  • There is no need to use DI container for this test.

    Here a reason why you could use DI container to resolve concrete class: all other tests use similar pattern to construct type via container and this one just happen to not require dependencies.

    Unity sample:

    [TestMethod]
    public void DoesSomething_behaves_correctly()
    {
         var expected = 42;
         var container = new UnityContainer();
         var foo = container.Resolve<DoesSomething>(); 
         int actual = foo.DoesImportant(21, 21); 
    
         Assert.AreEqual(expected, actual); 
    }
    

    Side benefit of this approach is that your test needs minimal changes when DoesSomething start having dependencies.