c# - 使用 Moq 和 MSTest 测试异常的正确方法

标签 c# .net unit-testing moq mstest

对于 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;
    }
}

如果出现以下情况,上述代码段将失败:

  1. 引发了错误的异常
  2. 没有出现异常
  3. 你的一个断言失败了。

顺便说一句,因为你在方法中的捕获不是 Exception 而不是 ApplicationException,我建议你将设置更改为:

_cartDatabaseMock.Setup(c => c.SaveCart(_cart)).Throws<Exception>();

关于c# - 使用 Moq 和 MSTest 测试异常的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37311645/

相关文章:

c# - 当 DB 消失时,MySqlConnection Connect() 方法抛出异常的速度非常慢 C#

c# - 在 C# 中覆盖事件真的会出错吗?

c# - 如何替换 ASP.NET Core View 类的 "Request"类方法?

c# - 使用 App.Config 对 C# 程序集进行单元测试返回异常

android - 如何使用 Android gradle 插件 0.10.0 或更高版本获取 jacoco 覆盖率报告?

ruby-on-rails - 测试突然出错。有人看到这个错误吗?

mysql - 在 rails 中生成数据的单元测试中按 created_at 排序

c# - C# 中不明确的函数/构造函数调用

c# - 为基类的每个 child 创建一个静态变量并获取它

c++ - 包装 C# C++