我对单元测试相当新,无法绕过如何正确测试(或者我应该如此)。
我有一个控制器方法(伪代码):
public ActionResult Register(formModel model)
{
if (ModelState.isValid) {
try {
_userService.CreateUser(a bunch of parameters here);
return RedirectToAction(some other action);
}
catch (Exception e)
{
ModelState.AddModelError("",e.Message);
}
}
return View();
}
我对“_userService”进行了一系列单独的测试。 “CreateUser”方法只是创建一个新用户并且不返回任何内容,如果出现错误(例如用户存在),我会在try catch中冒泡到控制器环绕并将异常添加到ModelState中。 / p>
根据我的理解,我应该模拟服务并声明它被正确调用(我使用assertwascalled语法),因为它什么都不返回,我只是想知道我的控制器调用它。
我不确定如何测试当用户服务抛出错误时它不应该重定向并且应该将该异常添加到模型状态。使用犀牛嘲讽,你可以存在一个模拟,但单元测试的书籍艺术建议反对。
现在在我的测试中我手动添加模型错误(如果它来自用户服务则不关心)并测试控制器是否存在错误时返回相同的视图。这是解决这个问题的正确方法吗?或者我应该创建一个单独的测试,我将_userService存根以抛出错误并检查它是否已添加到modelstate?或者我甚至不应该测试那个案子?我觉得我可能只是在分析整个事情,使用模型状态测试就足以满足这个......
答案 0 :(得分:1)
你的模拟代表一个合作类。我不会太嘲笑嘲笑和存根之间的区别;它仍然是一个合作班。
您可以将单元测试视为描述如何使用您的课程,以及课程如何与其协作者进行交互。你有两个例子:
Given a controller
When I register the model
Then the class should ask the user service to create a user.
和
Given a controller
Given the user service is broken
When I register the model
Then the class should attach the error to the model state.
这是第二个Given
告诉你你是顽固而不是嘲笑。您正在设置用户服务,好像它已经坏了。类的行为上下文是不同的,所以你需要存根,你应该确实抛出异常。
如果您将这些行作为注释添加到测试中,那么它将是有意义的。如果有意义,请忽略这本书。
BTW,这是单位级别的BDD。您可以在单元级别使用“Given,When,Then”,就像在场景级别一样,它可以帮助您考虑测试的逻辑。只是不要使用BDD场景工具。