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
?
source to share
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.
source to share
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.
source to share