假设我的动作看起来像这样:
...
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);
...
我应该为每种情况编写单独的单元测试:
或者我可以编写单个单元测试来验证上述两种情况吗?
答案 0 :(得分:0)
我会为每个beahviour创建一个测试。一个用于验证对Serialize的调用,另一个用于调用CreateAuthCookie。
这样,如果在某个时刻删除了其中一个调用,您只需删除相应的单元测试,而无需编辑现有调用。
此外,如果您以
的形式使用测试的命名约定void When_Calling_XXXX_With_YYYY_Then_ZZZZZ();
ZZZ部分将更具可读性
答案 1 :(得分:0)
我认为这完全是个人偏好,但我会在单个单元测试中验证两者。
我查看测试的方式是,给定某个上下文,可以获得一些结果。有时,这意味着需要调用多个方法或服务来实现该结果。设置auth cookie仅在Serialize()成功时才有意义,同样调用Serialize()的唯一原因是创建auth令牌。他们无法相互独立地运行,因此单元测试也不应该。 根据有效的用户名和密码,用户已登录。在这种情况下,它意味着您验证了用户的密码,并创建了包含必需数据的令牌。
另外,我认为实际上,所有的设置工作只是为了纯度"测试是浪费时间。其他答案提到如果您将来重构此操作,则更新测试的难易程度。根据我的经验,如果你重写它,那将是一个如此重大的变化,你无论如何都要重做测试。
有点偏离主题,但这就是我喜欢Machine.specifications测试框架的原因,因为您正在进行单一设置,但测试运行器会将您的每个验证视为单独的测试。
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()
}