对于 Moq 与 MsTest 的行为有点混淆。
编辑:这不是“我如何测试?”的问题。或“我如何断言?”,这是查看最小起订量如何工作的草稿本,因此不要关注异常类型等。
我认为更好的问题可能是 =>“Moq Throws<> 的行为类似于 MsTest ExpectedExceptionAttribute?”也就是说,他们期望在测试或 SUT 中出现异常?
我想知道最小起订量“Throws”在与 MsTest 一起使用时如何工作。不使用 MsTest 预期的异常属性是否更好?在测试中执行 try..catch 是否更好?关于这个我还有几个问题。
我正在模拟数据库调用,当发生错误时我想返回零 (0)。
TestMethod 直接使用 MsTest 异常属性,并使用 Moq 抛出异常。它仅在我在 SaveCart 方法中抛出异常时有效,而在我返回零时无效。
我想了解底层行为,因为感觉好像我不应该,也不想在 SaveCart 方法中抛出异常。
这里是有问题的测试:
[TestMethod]
[ExpectedException(typeof(ApplicationException))]
public void CartRepoSaveCartExceptionShouldReturnZero()
{
_cartDatabaseMock.Setup(c => c.SaveCart(_cart))
.Throws<ApplicationException>();
var result = _cartRepository.SaveCart(_cart);
Assert.AreEqual(result, _cartSaveExceptionValue);
}
这是基本的 SaveCart,它不会引发导致测试失败的异常:
public long SaveCart(Cart cart )
{
long returnValue;
try
{
returnValue = _cartDatabase.SaveCart(cart);
}
catch (Exception)
{
return 0;
}
return returnValue;
}
这是一个基本的 SaveCart,在其中测试有效,因为它抛出了异常:
public long SaveCart(Cart cart )
{
long returnValue;
try
{
returnValue = _cartDatabase.SaveCart(cart);
}
catch (Exception)
{
throw new ApplicationException();
}
return returnValue;
}
如果问题的解释不是很清楚,请随意为问题建议一个更好的标题。
最佳答案
你应该使用 ExpectedExceptionAttribute当被测单元抛出异常时。
在您的第一个示例中,该方法没有抛出任何异常,因此测试失败。
因为你的被测方法没有抛出任何异常你根本不需要使用这个属性...(在这种情况下只需验证返回值)
当您想要验证是否抛出异常并且想要验证是否发生了一些额外的操作时,请使用以下模式:
[TestMethod]
[ExpectedException(typeof(<The specific exception>))]
public void FooTest()
{
//arrange
try
{
// act
}
catch(<the specific exception>)
{
// some asserts
throw;
}
}
如果出现以下情况,上述代码段将失败:
- 引发了错误的异常
- 没有出现异常
- 你的一个断言失败了。
顺便说一句,因为你在方法中的捕获不是 Exception
而不是 ApplicationException
,我建议你将设置更改为:
_cartDatabaseMock.Setup(c => c.SaveCart(_cart)).Throws<Exception>();
关于c# - 使用 Moq 和 MSTest 测试异常的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37311645/