6.3. Solution

Let's implement the above design and refactor our tests and make sure that they work. We start by creating the interface:

public interface IMessageRepository
    int Add(Message message);
    bool Delete(int Id);
    bool Save(Message message);
IQueryable<Message> Get();


To improve the code's readability, I am going to rename the MessageService class to InMemoryMessageService. Later we will create a SqlMessageService class that will use a SqlMessageRepository.

Then we change the InMemoryMessageService to use the new repository:

public class InMemoryMessageService : IMessageService
    private IValidationRunner ValidationRunner { get; set; }
    private IMessageRepository Repository { get; set; }

    public InMemoryMessageService()
        : this(null, null)

    public InMemoryMessageService(IMessageRepository repository,
                          IValidationRunner validationRunner)
        ValidationRunner = validationRunner ?? new ValidationRunner();
        Repository = repository ?? new InMemoryMessageRepository();

Now we make sure we can build the projects and run all the tests. Once everything is fine, we write a new test to make sure that we are using the repository:

[Test] public void Create_Adds_Message_To_Repository() { //mock the repo var mockRepo = new Mock<IMessageRepository>(); //set expectations mockRepo.Expect(r => r.Add(model)).Returns(1); var mockValidationRunner = new Mock<IValidationRunner>(); var service = new InMemoryMessageService(mockRepo.Object, mockValidationRunner.Object); controller = new MessageController(service); ...

Get ASP.NET MVC 1.0 Test Driven Development: Problem - Design - Solution now with O’Reilly online learning.

O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.