NSubstitute,try catch 不适用于配置为抛出异常的异步方法
NSubstitute, try catch is not working on async method configured to throw an exception
我正在使用 NSubstitute 进行模拟和伪造。我正在使用 EF6 并希望设置数据库上下文的 SaveChangesAsync-Method 以引发异常:
context.SaveChangesAsync().Throws(new DbUpdateException("", SqlExceptionHelper.CreateSqlException(2627)));
在我的数据存储库的方法中调用 SaveChangesAsync,如下所示:
try
{
var fromDatabase = await context.Entries.OfType<Document>().FirstOrDefaultAsync(d => d.Id == doc.Id);
if (fromDatabase == null)
{
fromDatabase = new Document();
context.Entries.Add(fromDatabase);
}
PatchEntity(fromDatabase, doc);
await context.SaveChangesAsync();
}
catch (DbUpdateException ex)
{
var innerException = ex.InnerException as SqlException;
if (innerException != null && innerException.Number == 2627)
{
errors.Add(new DbValidationError(nameof(doc.Name), "A entry with the same Name already exists under the selected parent."));
}
}
这是我的单元测试中的行:
var result = await repository.TryAddOrUpdateDocument(doc);
不幸的是,我的测试一直失败,原因是我的测试方法 (!) 抛出了异常,我正在尝试捕捉。添加一般异常捕获块也不起作用,根本没有捕获到异常。异常正在冒泡。
我的测试被声明为 "public async Task...",但将其简单地转换为 void 并在我的存储库的异步方法上调用 .Result 也无济于事。怎么回事?
我不能 100% 确定,但您可能面临这样的问题,即无法自然捕获 async with void return 类型抛出的异常。在此处阅读 "Avoid Async Void" 部分:
https://msdn.microsoft.com/en-us/magazine/jj991977.aspx
即使不能解决您的问题,也值得一读...
我认为问题是异常是从原始调用中抛出的,而不是从返回的 Task
内部抛出的 described here。
试试这样的:
Func<int> throwDbEx = () => {
throw new DbUpdateException("", SqlExceptionHelper.CreateSqlException(2627));
};
context.SaveChangesAsync().Returns(Task.Run(throwDbEx));
我正在使用 NSubstitute 进行模拟和伪造。我正在使用 EF6 并希望设置数据库上下文的 SaveChangesAsync-Method 以引发异常:
context.SaveChangesAsync().Throws(new DbUpdateException("", SqlExceptionHelper.CreateSqlException(2627)));
在我的数据存储库的方法中调用 SaveChangesAsync,如下所示:
try
{
var fromDatabase = await context.Entries.OfType<Document>().FirstOrDefaultAsync(d => d.Id == doc.Id);
if (fromDatabase == null)
{
fromDatabase = new Document();
context.Entries.Add(fromDatabase);
}
PatchEntity(fromDatabase, doc);
await context.SaveChangesAsync();
}
catch (DbUpdateException ex)
{
var innerException = ex.InnerException as SqlException;
if (innerException != null && innerException.Number == 2627)
{
errors.Add(new DbValidationError(nameof(doc.Name), "A entry with the same Name already exists under the selected parent."));
}
}
这是我的单元测试中的行:
var result = await repository.TryAddOrUpdateDocument(doc);
不幸的是,我的测试一直失败,原因是我的测试方法 (!) 抛出了异常,我正在尝试捕捉。添加一般异常捕获块也不起作用,根本没有捕获到异常。异常正在冒泡。
我的测试被声明为 "public async Task...",但将其简单地转换为 void 并在我的存储库的异步方法上调用 .Result 也无济于事。怎么回事?
我不能 100% 确定,但您可能面临这样的问题,即无法自然捕获 async with void return 类型抛出的异常。在此处阅读 "Avoid Async Void" 部分: https://msdn.microsoft.com/en-us/magazine/jj991977.aspx 即使不能解决您的问题,也值得一读...
我认为问题是异常是从原始调用中抛出的,而不是从返回的 Task
内部抛出的 described here。
试试这样的:
Func<int> throwDbEx = () => {
throw new DbUpdateException("", SqlExceptionHelper.CreateSqlException(2627));
};
context.SaveChangesAsync().Returns(Task.Run(throwDbEx));