This builds on the previous example of the Greeter
class which has two dependencies, IGreetingProvider
and IGreetingWriter
.
The actual implementation of IGreetingProvider
might retrieve a string from an API call or a database. The implementation of IGreetingWriter
might display the greeting in the console. But because Greeter
has its dependencies injected into its constructor, it's easy to write a unit test that injects mocked versions of those interfaces. In real life we might use a framework like Moq, but in this case I'll write those mocked implementations.
public class TestGreetingProvider : IGreetingProvider
{
public const string TestGreeting = "Hello!";
public string GetGreeting()
{
return TestGreeting;
}
}
public class TestGreetingWriter : List<string>, IGreetingWriter
{
public void WriteGreeting(string greeting)
{
Add(greeting);
}
}
[TestClass]
public class GreeterTests
{
[TestMethod]
public void Greeter_WritesGreeting()
{
var greetingProvider = new TestGreetingProvider();
var greetingWriter = new TestGreetingWriter();
var greeter = new Greeter(greetingProvider, greetingWriter);
greeter.Greet();
Assert.AreEqual(greetingWriter[0], TestGreetingProvider.TestGreeting);
}
}
The behavior of IGreetingProvider
and IGreetingWriter
are not relevant to this test. We want to test that Greeter
gets a greeting and writes it. The design of Greeter
(using dependency injection) allows us to inject mocked dependencies without any complicated moving parts. All we're testing is that Greeter
interacts with those dependencies as we expect it to.