【问题标题】:Why can't I detect this Exception in my Tests为什么我不能在我的测试中检测到这个异常
【发布时间】:2020-02-05 14:20:40
【问题描述】:

我正在用 C# 中的 nUnit 编写一个 Intigration 测试。

我的代码是:

public async Task<bool> WriteData(Document data, string tableName)
{
   try
   {
      var table = Table.LoadTable(_dynamoDbClient, tableName);
      table.PutItem(data);
      return true;
   }
   catch (Exception e)
   {
     _logger.Info("Failed Writing Record");
     _logger.Info("Error: " + e.Message);
     return false;
   }
}

我的测试是:

public void TestToSeeIfWeGetAnExceptionWhenProvidingBadDataToTheDatabase()
{
   // arrange
   var item = new Document
   {
      ["Id"] = "1001",
      ["TransactionID"] = 111111,
      ["StatementType"] = "TestBank"
   };

   _bankStatementTable = "does-not-exist";

   // act / assert

   Assert.Catch<System.Exception>(() => _awsDynamoDbManager.WriteData(item, _bankStatementTable));
}

因为我将错误的数据传递给数据库,所以我预计会出现异常,但我得到了一个。
但是,测试失败。 我从测试运行者那里得到这条消息:

预期: 的实例

但是是:null

如果我在 Debug 中运行测试,我可以看到 Catch 被击中。 我错过了什么?

【问题讨论】:

  • 我认为Assert.Catch 仅适用于未应得的异常。
  • WriteData 在异常情况下返回false
  • 您正在使用被测主题中的异常。测试本身没有什么可捕捉的。您需要断言该测试用例的预期行为,即如果抛出异常,主题将返回 false

标签: c# unit-testing nunit


【解决方案1】:

您应该稍微更新一下您的代码。在 catch 块中重新抛出 Exception 并使用 ThrowsAsync

catch (Exception e)
{
     _logger.Info("Failed Writing Record");
     _logger.Info("Error: " + e.Message);
     throw;
}
...
Assert.ThrowsAsync<System.Exception>(async () => await _awsDynamoDbManager.WriteData(item, _bankStatementTable));

或者通过将测试也设为async 来检查WriteData 返回false 并调用Assert.IsFalse

public async Task TestToSeeIfWeGetAnExceptionWhenProvidingBadDataToTheDatabase()
{
   // arrange
   ...
   // act / assert

   var result = await _awsDynamoDbManager.WriteData(item, _bankStatementTable);
   Assert.IsFalse(result);
}

由于WriteData 方法中没有可等待的代码,您可以将其设为同步代码并使用Task.FromResult 作为返回结果,或者使其更简单并删除Task&lt;bool&gt; 的使用

public bool WriteData(Document data, string tableName)
{
   try
   {
      var table = Table.LoadTable(_dynamoDbClient, tableName);
      table.PutItem(data);
      return true;
   }
   catch (Exception e)
   {
     _logger.Info("Failed Writing Record");
     _logger.Info("Error: " + e.Message);
     return false; //or throw;
   }
}

以及同步测试代码

Assert.Throws<System.Exception>(() => _awsDynamoDbManager.WriteData(item, _bankStatementTable));

public void TestToSeeIfWeGetAnExceptionWhenProvidingBadDataToTheDatabase()
{
   // arrange
   ...
   // act / assert

   var result = _awsDynamoDbManager.WriteData(item, _bankStatementTable);
   Assert.IsFalse(result);
}

【讨论】:

  • 还应该提到被测方法实际上不是异步的,因为没有等待。他们可以将密集的内容包装在 Task.Run 或删除 async 并返回 Task.FromResult(true/false)
  • @Richard210363 是否回答了您的问题,您需要更多信息或详细信息吗?
【解决方案2】:

因为您在异常情况下返回 false:

catch (Exception e)
{
    _logger.Info("Failed Writing Record");
    _logger.Info("Error: " + e.Message);
    return false;
}

使用throw 子句。

【讨论】:

  • 返回 True 或 False 对测试结果没有影响。我仍然得到“空”
猜你喜欢
  • 2020-05-21
  • 2012-04-22
  • 2021-07-19
  • 2012-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多