views:

57

answers:

2

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

A: 

Well, 13 months later and no answers. Awesome.

Heres what i do now:

/tests/controllers/address/add/get.cs
/tests/controllers/address/add/valid.cs
/tests/controllers/address/add/invalid.cs
Andrew Bullock
+1  A: 

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.

iwein