patterncsharpMinor
Best testing using a mocked repository
Viewed 0 times
testingusingrepositorymockedbest
Problem
[Test]
public void Post_ReturnsCorrectModel()
{
var post = new Post
{
Slug = "continuing-to-an-outer-loop",
Title = "Continuing to an outer loop",
Summary = "When you have a nested loop, sometimes",
Content = "When you have a nested loop, sometimes",
PublishedAt = DateTime.Now.AddDays(7),
Tags = new Collection { new Tag { Name = "Programming" } }
};
repository.Setup(expression => expression.Find("continuing-to-an-outer-loop"))
.Returns(post);
var viewResult = (ViewResult) controller.Post("continuing-to-an-outer-loop");
var actual = viewResult.Model as PostViewModel;
Assert.NotNull(actual);
Assert.AreEqual(actual.Slug, post.Slug);
Assert.AreEqual(actual.Title, post.Title);
Assert.AreEqual(actual.Summary, post.Summary);
Assert.AreEqual(actual.Content, post.Content);
Assert.AreEqual(actual.PublishedAt, post.PublishedAt);
Assert.AreEqual(actual.Tags, post.Tags);
}Hopefully the purpose of this test is already clear but to further clarify - the repository exposes a
Post object that is mapped to a PostViewModel. I then proceed to assert that the action method returns the correct model.The action method looks like this:
public ActionResult Post(string slug)
{
Post post =
repository.Find(slug);
if (post == null || post.Draft)
{
return HttpNotFound();
}
return View("Post", post.MapTo());
}Could you please review this test? My particular areas of concern are as follows:
- Is the test well named? (I adopted the name from here).
- Must I assert that each property is equal as I have above? I feel as though I can make a reasonable assumption that if one property is equal then the rest will be too.
- Here I am modelling the
postobject based on a real blog post. I do not think that the value of each property really matters and that I could very well have used arbitrary strings. Are there any
Solution
-
I think the test is reasonably well named (imho).
-
If you assume you write the test against a black box (meaning you don't know how the controller code is implemented) then yes you should compare all properties. Someone could have forgotten to copy a property for example. This is especially the case for later when new properties get added (as a regression test). If you find yourself writing code like that a lot then there are several ways to automate this comparison.
-
I prefer to use human readable strings in unit tests. Makes it easier to read. However once you start doing integrations tests like hitting a test database you want to possibly generate some more exotic strings (non latin characters) to make sure that what you put into the db is also what you get back out and not some garbled nonsense. Some databases can be nasty in that regard.
-
If you find yourself creating the same
I think the test is reasonably well named (imho).
-
If you assume you write the test against a black box (meaning you don't know how the controller code is implemented) then yes you should compare all properties. Someone could have forgotten to copy a property for example. This is especially the case for later when new properties get added (as a regression test). If you find yourself writing code like that a lot then there are several ways to automate this comparison.
-
I prefer to use human readable strings in unit tests. Makes it easier to read. However once you start doing integrations tests like hitting a test database you want to possibly generate some more exotic strings (non latin characters) to make sure that what you put into the db is also what you get back out and not some garbled nonsense. Some databases can be nasty in that regard.
-
If you find yourself creating the same
post over and over again then you have some options:- If it's just inside one test fixture then create the post in the
Setuproutine.
- If it's across multiple test fixtures then yes extract it into a test utility class.
Context
StackExchange Code Review Q#58210, answer score: 3
Revisions (0)
No revisions yet.