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

Dependency Inclusion can be very useful for testing modules with dependencies. This is not the point.


Let's say there is a concrete implementation,

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

      

which implements this,

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

      

In a unit test, you can obviously new

execute 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 doesn't matter for the principle of the 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 good reason to put IDoesSomething

in a test? Or, is there a good reason not to enter IDoesSomething

?

+3


source to share


2 answers


It is not necessary to use a DI container for this test.

This is the reason why you can use a DI container to solve a specific class: all other tests use a similar pattern for building the type through the container, and it just doesn't require dependencies.

Unity Pattern:



[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); 
}

      

The advantage of this approach is that your test requires minimal changes when it DoesSomething

starts to have dependencies.

+2


source


Your tests should be written specifically for a specific implementation.

Take this for example:

public void DoTestA()
{
    ObjectFactory.Set<IDoesSomething, DoesSomethingBadly>();

    var doesSomething = ObjectFactory.Get<IDoesSomething>();
    Assert.AreEqual(0, doesSomething.Add(1,1));
}

public void DoTestB()
{
    int expected = 42; 

    //This test is now *completely* dependent on DoTestA, and can give different results
    //depending on which test is run first. Further, we don't know
    //which implementation we're testing here. It not immediately clear, even if
    //there only one implementation.
    //As its a test, it should be very explicit in what it testing.

    IDoesSomething foo = ObjectFactory.Get<IDoesSomething>(); 
    int actual = foo.DoesImportant(21, 21); 

    Assert.AreEqual(expected, actual); 
}

// Define other methods and classes here
public class DoesSomething : IDoesSomething 
{
    public int Add(int x, int y) 
    { 
        return x+y;
    }
}

public class DoesSomethingBadly : IDoesSomething
{
    public int Add(int x, int y)
    {
        return x-y;
    }
}

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

      



In tests, referring to the class directly is definitely the way to go. We don't care what the interface is, we only care about the specific implementation.

var foo = new DoesSomething();

is definitely the best option.

IDoesSomething foo = new DoesSomething();

not harmful, but it seems completely unnecessary since again we care about the implementation, not the interface.

+2


source







All Articles