xUnit测试:如何验证抛出两种不同异常中的一种
可行的实现方式
针对你遇到的泛型参数无法使用变量的问题,有几种实用的解决办法:
1. 使用非泛型重载的Assert.Throws
主流测试框架(如xUnit、NUnit)都提供了接受Type参数的非泛型Assert.Throws方法,直接传入你判断好的异常类型即可:
Type exceptionDuplicate = UseInMemoryDb ? typeof(ArgumentException) : typeof(DbUpdateException); Assert.Throws(exceptionDuplicate, () => context.SaveChanges());
该方法会验证执行委托时是否抛出了指定类型(或其子类型)的异常,行为和泛型版本完全一致。
2. 分支判断调用泛型方法
如果更偏好泛型写法,可以直接根据UseInMemoryDb的值分支处理:
if (UseInMemoryDb) { Assert.Throws<ArgumentException>(() => context.SaveChanges()); } else { Assert.Throws<DbUpdateException>(() => context.SaveChanges()); }
这种方式代码直观易懂,适合简单的分支场景。
3. 反射调用泛型方法(复杂场景备选)
如果需要更灵活的泛型调用,可通过反射构造并调用泛版Assert.Throws:
Type exceptionDuplicate = UseInMemoryDb ? typeof(ArgumentException) : typeof(DbUpdateException); // 获取泛型方法定义 var throwsMethodDef = typeof(Assert).GetMethod("Throws", new[] { typeof(Action) }); // 构造特定类型的泛型方法 var genericThrowsMethod = throwsMethodDef.MakeGenericMethod(exceptionDuplicate); // 执行方法 genericThrowsMethod.Invoke(null, new object[] { (Action)(() => context.SaveChanges()) });
这种写法相对繁琐,仅推荐在特殊复杂场景下使用。
内容的提问来源于stack exchange,提问作者David Thielen
相关产品推荐
相关产品推荐

