我在界面中有以下方法..
Task<SearchResult<T>> SearchAsync(TU searchOptions);
效果很好。
现在我正在尝试进行单元测试,以便在出现问题时进行测试 - 并且代码会抛出异常。
在这种情况下,我设置了我的方法来抛出HttpRequestException
。我的单元测试未能说我扔了那个例外..
var result = Should.Throw<HttpRequestException>
(async () => await service.SearchAsync(searchOptions));
单元测试的错误消息是
Shouldly.ChuckedAWobbly
var result =应该是 扔
System.Net.Http.HttpRequestException
但不是
所以assertion framework说的是:你预料到一个例外,但没有一个被抛出。
当我逐步执行代码时,异常被100%抛出。
有人能看到我的单元测试代码出错吗?
答案 0 :(得分:13)
问题是您的断言框架不了解异步方法。我建议你提出问题。
与此同时,您可以使用source for Should.Throw
撰写自己的MyShould.ThrowAsync
:
public static async Task<TException> ThrowAsync<TException>(Func<Task> actual)
where TException : Exception
{
try
{
await actual();
}
catch (TException e)
{
return e;
}
catch (Exception e)
{
throw new ChuckedAWobbly(new ShouldlyMessage(typeof(TException), e.GetType()).ToString());
}
throw new ChuckedAWobbly(new ShouldlyMessage(typeof(TException)).ToString());
}
并按原样使用:
var result = await MyShould.ThrowAsync<HttpRequestException>
(async () => await service.SearchAsync(searchOptions));
或稍微简单和等效:
var result = await MyShould.ThrowAsync<HttpRequestException>
(() => service.SearchAsync(searchOptions));
答案 1 :(得分:3)
单元测试异步代码/功能非常困难。我自己正在进行单元测试异步并遇到与你一样的问题。
我发现以下两个资源非常有用:
答案 2 :(得分:3)
问题是传递的lambda返回一个Task。如果Should.Throw
等待完成此任务,则只能观察到引发的异常,显然它不会。作为解决方法,您可以.Wait
自己SearchAsync
返回任务。{/ p>
mstest
(内置的visual studio测试框架)支持自Visual Studio 2012以来的异步测试。您基本上可以通过替换&#34; void&#34;来更改测试方法声明。 by&#34; async Task&#34;。
[TestMethod]
[ExpectedException(typeof(System.Net.Http.HttpRequestException))]
public async Task SomeTest()
{
await service.SearchAsync(searchOptions);
}
您可能正在使用不同的单元测试框架,但不清楚哪一个。请查阅其文档以了解它是否支持异步测试。
NUnit 2.6.3似乎也支持异步测试。
编辑:所以您正在使用xUnit。这个特殊问题是fixed for xUnit 2.0。它目前仍然是阿尔法。
答案 3 :(得分:2)
异常抛出在与运行单元测试的线程不同的线程上。单元测试框架只能预测其自己的线程上的异常。
我建议您在服务的同步版本上测试异常。
答案 4 :(得分:2)
像这样测试:
var result = Should.Throw<HttpRequestException>
(() => service.SearchAsync(searchOptions).Result);
或者:
var result = Should.Throw<HttpRequestException>
(() => service.SearchAsync(searchOptions).Wait());
否则,Should.Throw
在async
lambda完成之前返回。
答案 5 :(得分:0)
今天应该包含Should.ThrowAsync<T>
。
您可以像这样使用它:
await Should.ThrowAsync<HttpRequestException>(() => service.SearchAsync(searchOptions));