我不知道为什么我的单元测试失败了: 测试方法:
let result = search<Artist>('someQuery', 'artist');
单元测试:
public async Task<MyType> Get(string externalId)
{
if (externalId == null)
throw new ArgumentNullException();
if (externalId == "" || externalId == " ")
throw new FormatException();
// ...
}
然后失败,因为错误消息显示:
预计会抛出ArgumentNullException,但不会抛出execption。
这很奇怪,因为在调试此测试时抛出了异常行!
我正在使用xunit和fluentasserttions。
答案 0 :(得分:0)
这一行是问题所在:
Action action = async () => await controller.Get(null);
它创建了一个async void
方法,这使得观察异常非常困难(从而进行适当的测试)。
Last time I checked,Fluent Assertions只支持反模式样式的“异步”断言:
sut.Awaiting(…).ShouldThrow<T>();
不幸的是,这会使用阻塞同步异步黑客,因此当与单线程SynchronizationContext
一起使用时,它是bound to fail。哦,猜猜which unit testing framework provides a single-threaded SynchronizationContext
?如果您猜到xUnit,那么您将获得奖品。
因此,“异步”FA测试不适用于开箱即用的xUnit。你有几个选择。
您可以通过在线程池线程上运行整个测试来避免xUnit的上下文;这是低效的,但会完成工作:
await Task.Run(() =>
{
controller.Awaiting(c => c.Get(null)).ShouldThrow<ArgumentNullException>();
});
不完全漂亮。
或者,您可以使用自己的异步兼容断言,例如the one I wrote:
await AsyncAssert.ThrowsAsync<ArgumentNullException>(() => controller.Get(null));