我有一个使用yield return的项目,并且不明白为什么XUnit在MSTest传递时未能在我的单元测试中捕获异常。
这是我的虚拟代码。
奇怪的是,如果我使用我的私有方法EnumerableYieldReturn,并将该逻辑直接放在我的公共方法YieldReturnList中,结果会随着XUnit测试传递和MSTest失败而翻转。
[TestClass]
public class MSTestRunner
{
[TestMethod]
[ExpectedException(typeof(ArgumentException))]
public void MSTestUsingExpectedException()
{
var sut = new YieldReturn();
sut.YieldReturnList(null);
}
}
public class XUnitRunner
{
[Fact]
[ExpectedException(typeof(ArgumentException))]
public void XUnitUsingExpectedException()
{
var sut = new YieldReturn();
sut.YieldReturnList(null);
}
}
public class YieldReturn
{
public IEnumerable<string> YieldReturnList(int? value)
{
if (value == null)
throw new ArgumentException();
return EnumerableYieldReturn((int)value);
}
private IEnumerable<string> EnumerableYieldReturn(int value)
{
var returnList = new List<string>() { "1", "2", "3" };
for (int i = 0; i < value; i++)
{
yield return returnList[i];
}
}
}
我可以通过从sut.YieldReturnList分配返回对象并尝试迭代它来传递它们,但这并不能解释为什么一个框架正在传递而另一个框架失败...
答案 0 :(得分:4)
&#34; xUnit.net废除了ExpectedException属性,转而使用Assert.Throws。&#34;来自https://xunit.github.io/docs/comparisons.html。
结果翻转的原因是不再抛出异常:
MSTest:期望异常,因为它使用了属性,因此失败,因为它没有得到异常
XUnit:忽略expect异常属性,因为框架没有使用它,因此传递是因为异常没有导致测试失败。
如果更改方法不再抛出异常的原因更复杂,但它基本上与为使用yield关键字的方法创建状态机有关。目前,您的公共方法不直接使用yield关键字,因此它被视为普通函数,因此执行null检查并在调用方法后立即抛出异常。将yield关键字移动到public方法使其成为一个惰性状态机,因此它不会执行null检查以抛出异常,直到您开始迭代IEnumerable。