我有一个用于捕获 SqlException 的代码。我根据此处列出的答案编写了一个处理 SQLException 的测试:How to throw a SqlException when need for mocking and unit test?
[TestMethod]
public async Task TestFailJobOnSqlExceptionAsync()
{
_context.Setup(x => x.CallSubOrchestratorAsync()
.Throws(MakeSqlException());
var orchestratorFunction = new OrchestratorFunction(_configuration.Object, _loggingRepository.Object);
await orchestratorFunction.RunOrchestratorAsync(_context.Object, _executionContext.Object);
_log.Verify(x => x.LogMessageAsync(
It.Is<LogMessage>(m => m.Message.StartsWith($"Caught SqlException")),
It.IsAny<VerbosityLevel>(),
It.IsAny<string>(),
It.IsAny<string>()), Times.Never());
}
public static SqlException MakeSqlException()
{
SqlException exception = null;
try
{
SqlConnection conn = new SqlConnection(@"Data Source=.;Database=GUARANTEED_TO_FAIL;Connection Timeout=1");
conn.Open();
}
catch (SqlException ex)
{
exception = ex;
}
return (exception);
}
运行此程序时,我的测试失败并出现错误
测试方法 Services.Tests.TestFailJobOnSqlExceptionAsync 抛出异常: Microsoft.Data.SqlClient.SqlException:建立与 SQL Server 的连接时发生与网络相关或特定于实例的错误。服务器未找到或无法访问。验证实例名称是否正确以及 SQL Server 是否配置为允许远程连接。 (提供程序:命名管道提供程序,错误:40 - 无法打开与 SQL Server 的连接) ---> System.ComponentModel.Win32Exception:系统找不到指定的文件。
我错过了什么?
在编写单元测试时,您想要断言抛出特定异常,您将使用测试上方的
[ExpectedException(typeof(Microsoft.Data.SqlClient.SqlException))]
属性。
当属性丢失时,测试会失败,因为测试框架不理解您正在期待异常。
[TestMethod]
[ExpectedException(typeof(Microsoft.Data.SqlClient.SqlException))]
public async Task TestFailJobOnSqlExceptionAsync()
{
_context.Setup(x => x.CallSubOrchestratorAsync()
.Throws(MakeSqlException());
var orchestratorFunction = new OrchestratorFunction(_configuration.Object, _loggingRepository.Object);
await orchestratorFunction.RunOrchestratorAsync(_context.Object, _executionContext.Object);
_log.Verify(x => x.LogMessageAsync(
It.Is<LogMessage>(m => m.Message.StartsWith($"Caught SqlException")),
It.IsAny<VerbosityLevel>(),
It.IsAny<string>(),
It.IsAny<string>()), Times.Never());
}
如果您想验证记录器是否被调用,您需要在设置周围编写一个 try catch 块,直到验证方法为止。
[TestMethod]
public async Task TestFailJobOnSqlExceptionAsync()
{
try
{
_context.Setup(x => x.CallSubOrchestratorAsync()
.Throws(MakeSqlException());
var orchestratorFunction = new OrchestratorFunction(_configuration.Object, _loggingRepository.Object);
await orchestratorFunction.RunOrchestratorAsync(_context.Object, _executionContext.Object);
} catch(Exception)
{
}
_log.Verify(x => x.LogMessageAsync(
It.Is<LogMessage>(m => m.Message.StartsWith($"Caught SqlException")),
It.IsAny<VerbosityLevel>(),
It.IsAny<string>(),
It.IsAny<string>()), Times.Never());
}