I'm looking for tidy suggestions on how people organise their controller tests.
For example, take the "add" functionality of my "Address" controller,
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Add()
{
var editAddress = new DTOEditAddress();
editAddress.Address = new Address();
editAddress.Countries = countryService.GetCountries();
return View("Add", editAddress);
}
[RequireRole(Role = Role.Write)]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Add(FormCollection form)
{
// save code here
}
I might have a fixture called "when_adding_an_address"
, however there are two actions i need to test under this title...
I don't want to call both actions in my Act()
method in my fixture, so I divide the fixture in half, but then how do I name it?
"When_adding_an_address_GET"
and "When_adding_an_address_POST"
?
things just seems to be getting messy, quickly.
Also, how do you deal with stateless/setupless assertions for controllers, and how do you arrange these wrt the above? for example:
[Test]
public void the_requesting_user_must_have_write_permissions_to_POST()
{
Assert.IsTrue(this.SubjectUnderTest.ActionIsProtectedByRole(c => c.Add(null), Role.Write));
}
This is custom code i know, but you should get the idea, it simply checks that a filter attribute is present on the method. The point is it doesnt require any Arrange()
or Act()
.
Any tips welcome!
Thanks
In my opinion you should forget about naming your tests after the methods you're testing. In fact testing a single method is a strange concept. You should be testing a single thing a client will do with your code. So for example if you can hit add with a POST and a GET you should write two tests like you suggested. If you want to see what happens in a certain exceptional case you should write another test.
I usually pick names that tell a maintainer what he needs to know in Java:
@Test public void shouldRedirectToGetWhenPostingToAdd(){
//...
}
You can do this in any language and pick any *DD naming convention if you like, but the point is that the test name should convey the expectations and the scenario. You will get very small test this way and I consider this a good thing.