Asp.net mvc MVC控制器操作单元测试的粒度
假设我有一个动作,看起来像这样:Asp.net mvc MVC控制器操作单元测试的粒度,asp.net-mvc,unit-testing,Asp.net Mvc,Unit Testing,假设我有一个动作,看起来像这样: ... var userInfo = authService.SignIn(signInModel.UserName, signInModel.Password); if (userInfo == null) { ModelState.AddModelError("", "Invalid username/password"); return RedirectToAction(MVC.Home.Index()); } var user
...
var userInfo = authService.SignIn(signInModel.UserName, signInModel.Password);
if (userInfo == null)
{
ModelState.AddModelError("", "Invalid username/password");
return RedirectToAction(MVC.Home.Index());
}
var userData = new UserData
{
UserID = userInfo.UserID,
Name = userInfo.Name,
Email = userInfo.Email,
Roles = userInfo.Roles
};
string serializedUserData = textSerializer.Serialize(userData);
formsAuthHelper.CreateAuthCookie(userInfo.UserName, serializedUserData);
...
我是否应该为每个场景编写单独的单元测试:
- 验证Serialize方法是否调用过一次
- 验证是否调用了CreateAuthCookie方法一次
或者我可以编写一个单单元测试来验证上述两种功能吗 我会为每个beahviour创建一个测试。一个用于验证对序列化的调用,另一个用于对CreateAuthCookie的调用 这样,如果某个调用被删除,您只需要删除相应的单元测试,而无需编辑现有的单元测试 此外,如果您以以下形式为测试使用命名约定:
void When_Calling_XXXX_With_YYYY_Then_ZZZZZ();
ZZZ部分将更具可读性我认为这完全是个人偏好,但我将在单个单元测试中验证这两个部分 我对测试的看法是,在特定的环境下,会取得一些结果。有时,这意味着需要调用多个方法或服务来实现该结果。设置auth cookie仅在Serialize()成功时才有意义,同样,调用Serialize()的唯一原因是创建auth令牌。它们不能独立运行,因此单元测试也不应该独立运行。给定有效的用户名和密码,用户即已登录。在本例中,这意味着您验证了用户的密码,并使用必需的数据创建了一个令牌 另外,我认为在实践中,仅仅为了测试的“纯度”而做所有的设置工作是浪费时间的。另一个答案是,如果您将来重构此操作,那么更新测试的难度会很大。根据我的经验,如果你真的重写了它,这将是一个巨大的变化,你将不得不重做测试 有点离题,但这就是为什么我喜欢测试框架,因为您只进行一次设置,但测试运行程序将每个验证视为单独的测试
public class when_calling_login_with_a_valid_username_and_password
{
Because of = () => controller.Login(...);
It should_call_serialize = () => textSerializer.Serialize().MustHaveBeenCalled();
It should_set_the_auth_token = () => formsAuthHelper.CreateAuthCookie().MustHaveBeenCalled()
}