你如何组织你的MVC控制器测试?

时间:2009-04-15 09:31:20

标签: unit-testing code-organization

我正在寻找关于人们如何组织控制器测试的整洁建议。

例如,使用“地址”控制器的“添加”功能

[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
}

我可能有一个名为"when_adding_an_address"的夹具,但是我需要在这个标题下测试两个动作......

我不想在我的夹具中调用Act()方法中的两个动作,所以我将夹具分成两半,但是我如何命名呢?

"When_adding_an_address_GET""When_adding_an_address_POST"

事情似乎很快就会变得混乱。

另外,如何处理控制器的无状态/无设置断言,以及如何安排这些以上的操作?例如:

[Test]
public void the_requesting_user_must_have_write_permissions_to_POST()
{
    Assert.IsTrue(this.SubjectUnderTest.ActionIsProtectedByRole(c => c.Add(null), Role.Write));
}

这是我知道的自定义代码,但你应该明白,它只是检查方法中是否存在过滤器属性。关键是它不需要任何Arrange()Act()

欢迎任何提示!

由于

2 个答案:

答案 0 :(得分:1)

在我看来,你应该忘记在你测试的方法之后命名你的测试。实际上,测试单个方法是一个奇怪的概念。您应该测试客户端对您的代码执行的任何操作。因此,例如,如果你可以使用POST和GET命中add,你应该像你建议的那样编写两个测试。如果你想看看在特殊情况下会发生什么,你应该写另一个测试。

我通常选择能告诉维护者他需要在Java中知道的名字:

@Test public void shouldRedirectToGetWhenPostingToAdd(){
    //...
}

如果您愿意,可以使用任何语言执行此操作并选择任何* DD命名约定,但重点是测试名称应表达期望和方案。你将以这种方式进行非常小的测试,我认为这是一件好事。

答案 1 :(得分:0)

好吧,13个月后,没有答案。真棒。

这是我现在所做的事情:

/tests/controllers/address/add/get.cs
/tests/controllers/address/add/valid.cs
/tests/controllers/address/add/invalid.cs