假设我有这段代码:
[HttpPost]
public ActionResult Edit(MyViewModel viewModel)
{
if (ModelState.IsValid)
{
_myRepository.SaveStuff(viewModel.Property1, viewModel.Property2);
return RedirectToAction("MyAction", "MyController");
}
else
{
return View("Edit", viewModel);
}
}
这是ASP.NET MVC,但这实际上与我的问题无关。真正的一点是,只有满足需求时才会调用方法(SaveStuff)。现在我想为这种方法编写单元测试......
我测试了调用存储库中的方法,并在modelstate有效时返回RedirectToRoute。我测试当模型状态无效时返回ViewResult。
我的问题是,我是否还应该编写一个测试,以确保当模型状态无效时,存储库中的方法是而不是?这似乎是一个好的测试必须确保我没有得到任何不需要的保存。但是我觉得,如果我沿着这条路走下去,测试那些事情就不会发生,我必须写的测试数量会增加很多......
答案 0 :(得分:4)
该方法有多少路径?
测试它们是否有意义?如果模型状态无效,保存它会是错误吗?
确保不发生的事情的数量通常受到被测方法的背景的限制;如果模型无效(我假设),则重要的是不保存模型。
答案 1 :(得分:4)
回答你的问题,是的。你应该测试一个方法在不应该调用时不会被调用。您绝对不希望您的应用程序持久存储无效数据。
如果将所有内容分解为单独的测试,那么测试的数量也会增加,这也是正确的。您的测试可以有多个断言。当状态无效时,我会将两个断言结合起来。这将使你免于编写几乎相同的测试。
答案 2 :(得分:1)
我的问题是,我是否还应该编写一个测试,以确保当模型状态无效时,不会调用存储库中的方法?这似乎是一个很好的测试,必须确保我没有得到任何不必要的保存。但是我觉得,如果我沿着这条路走下去,测试那些事情就不会发生,我必须写的测试数量会增加很多......
我的答案一般都是肯定的,但你真的应该考虑测试的是你的。你应该测试任何让你担心的事情。
在这种情况下,只添加一个测试。它不应该添加很多。
答案 3 :(得分:1)
您想测试所有代码路径。如果它真的不会发生那么你甚至不需要if
声明吗?我希望你为这个方法写两个测试:
// Note: I don't do .NET, so pardon any basic errors
// and hopefully the intent shows through.
[SetUp]
public void SetUp()
{
repository = new MockWidgetRepository()
controller = new WidgetController(repository);
}
[Test]
public void savesValidWidgets()
{
var result = controller.Edit(new ValidViewModel());
Assert.IsTrue(repository.SaveWasCalled());
Assert.AreEqual(typeof(RedirectResult), result.GetType());
}
这代表了你提到的第一个案例。然而,第二个是相似的。
[Test]
public void InvalidWidgetsAreRedisplayed()
{
var result = controller.Edit(new InvalidViewModel());
Assert.AreEqual(typeof(ViewResult), result.GetType());
}
希望有所帮助!
布兰登
答案 4 :(得分:0)
是的,但是我测试它的方式是有两个测试用例,一个是有效的,一个是无效的,当你运行每个case记录时,被测试代码所要求的保存顺序。
对于每个测试用例,检查它是否导致正确的保存顺序 - 对于有效案例恰好完全一次保存(使用正确的参数),并且完全对于无效案例,em>零保存。
我的一般原因是,在可能的情况下,不最好为每个被测代码区别对待的案例提供不同的测试代码。如果你有不同的测试数据通过相同的测试代码运行,那么当你编写测试代码时,你将弄乱你在应用程序代码中搞砸的相同边缘情况。因此,我尝试使用“放入此输入并检查输出和副作用是否符合预期”形式的公共代码来构造尽可能多的给定函数的测试。希望您最终能够以这种方式减少测试代码,因为您系统地测试所有输入的所有副作用,而不是为每个输入编写单独的代码。
如果你真的很幸运,你将来可以通过添加测试用例来添加回归测试和新功能测试,而无需编写任何新的测试代码。
答案 5 :(得分:0)
是的,您应该测试未调用_repository.SaveStuff
。实际上你需要编写四个测试。
ModelState.IsValid
= SaveStuff
Not ModelState.IsValid
=不SaveStuff
ModelState.IsValid
= return RedirectToAction
Not ModelState.IsValid
= return View
如果您在问题中说明,您同时测试了SaveStuff
和RedirectAction
,那么您将进行一次脆弱的测试。
使用相同的equivelant代码来显示正在发生的事情:
[HttpPost]
public ActionResult Edit(MyViewModel viewModel)
{
if (ModelState.IsValid)
{
_myRepository.SaveStuff(viewModel.Property1, viewModel.Property2);
}
if (ModelState.IsValid)
{
return RedirectToAction("MyAction", "MyController");
}
return View("Edit", viewModel);
}