I have a repository called PostsRepository
who implements an interface called IPostsRepository
:
public interface IPostsRepository
{
IEnumerable<Post> All();
}
public class PostsRepository : IPostsRepository
{
private readonly DatabaseContext context;
public PostsRepository(DatabaseContext context)
{
this.context = context;
}
public IEnumerable<Post> All()
{
return context.Posts.OrderBy(post => post.PublishDate);
}
}
And I have a controller called HomeController
who uses the aforementioned repository:
public class HomeController : Controller
{
private readonly IPostsRepository repository;
public HomeController(IPostsRepository repository)
{
this.repository = repository;
}
public ViewResult Index()
{
return View(repository.All());
}
}
These classes are currently resoundingly simple because they are experimental. Now for each of these classes, I have unit tests:
[TestFixture]
public class PostsRepositoryTest
{
private PostsRepository repository;
private MockDbSet<Post> databaseSet;
private Mock<DatabaseContext> databaseContext;
[SetUp]
public void SetUp()
{
databaseSet = new MockDbSet<Post>();
databaseSet.SetupLinq();
databaseContext = new Mock<DatabaseContext>();
databaseContext.Setup(context => context.Posts).Returns(databaseSet.Object);
repository = new PostsRepository(databaseContext.Object);
}
[Test]
public void All_ReturnsAllPosts()
{
databaseSet.SetupSeedData(Enumerable.Repeat(new Post(), 2));
var actual = repository.All();
Assert.AreEqual(2, actual.Count());
}
[Test]
public void All_ReturnsAllPostsOrderedByPublishDate()
{
databaseSet.SetupSeedData(new List<Post>
{
new Post { PublishDate = new DateTime(2014, 2, 1) },
new Post { PublishDate = new DateTime(2014, 1, 1) },
});
var actual = repository.All();
var expected = databaseSet.Data.OrderBy(post => post.PublishDate);
Assert.AreEqual(expected, actual);
}
}
[TestFixture]
public class HomeControllerTest
{
private Mock<IPostsRepository> repository;
private HomeController controller;
[SetUp]
public void SetUp()
{
repository = new Mock<IPostsRepository>();
controller = new HomeController(repository.Object);
}
[Test]
public void Index_RendersCorrectView()
{
controller.WithCallTo(c => c.Index())
.ShouldRenderDefaultView();
}
[Test]
public void Index_ReturnsCorrectModelType()
{
var actual = controller.Index().Model;
Assert.That(actual, Is.AssignableTo<IEnumerable<Post>>());
}
[Test]
public void Index_EmptyRepository_ReturnsNoPosts()
{
var actual = (IEnumerable<Post>) controller.Index().Model;
Assert.AreEqual(0, actual.Count());
}
[Test]
public void Index_ReturnsAllPosts()
{
var posts = Enumerable.Repeat(new Post(), 5);
repository.Setup(repo => repo.All()).Returns(posts);
var actual = (IEnumerable<Post>) controller.Index().Model;
Assert.AreEqual(posts.Count(), actual.Count());
}
}
As you can see, I have a test for the repository by the name of All_ReturnsAllPostsOrderedByPublishDate
which asserts that the posts are ordered by their publish date.
I wonder if I should test the same thing in the controller. On one hand, I do not as feel as though testing this behaviour again will add any value. But on the other hand, I worry that the controller is not bound to use the repository and that if the controller stops depending on / using the repository class, the test will break. I am inclined to verify that the controller calls the repository but as I interpret it, this answerer says that I shouldn't.
With that concern in mind, would you please review the correctness of my unit tests? Please identify any other concerns.