具有 ExpectedException 的 XUnit 和 MSTest 返回不同的结果
XUnit and MSTest with ExpectedException Returning Different Results
我有一个项目正在使用 yield return,但我不明白为什么在 MSTest 通过时 XUnit 无法在我的单元测试中捕获异常。
这是我的虚拟代码。
奇怪的是,如果我采用我的私有方法 EnumerableYieldReturn,并将该逻辑直接放入我的 public 方法 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 分配 return 对象并尝试遍历它来让它们都通过,但这并不能解释为什么一个框架通过而另一个框架失败。 ..
"xUnit.net has done away with the ExpectedException attribute in favor of Assert.Throws." 来自 https://xunit.github.io/docs/comparisons.html.
结果翻转的原因是不再抛出异常所以:
MSTest:因为它使用了属性而期望异常,因此失败,因为它没有得到异常
XUnit:忽略 expect 异常属性,因为框架不使用它,因此通过,因为异常没有导致测试失败。
更改方法后不再抛出异常的原因比较复杂,但它基本上与为使用 yield 关键字的方法创建状态机有关。目前,您的 public 方法不直接使用 yield 关键字,因此它被视为普通函数,因此会在调用该方法后立即执行 null 检查并抛出异常。将 yield 关键字移动到 public 方法使其成为惰性状态机,因此它不会执行 null 检查以抛出异常,直到您开始迭代 IEnumerable。
我有一个项目正在使用 yield return,但我不明白为什么在 MSTest 通过时 XUnit 无法在我的单元测试中捕获异常。
这是我的虚拟代码。
奇怪的是,如果我采用我的私有方法 EnumerableYieldReturn,并将该逻辑直接放入我的 public 方法 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 分配 return 对象并尝试遍历它来让它们都通过,但这并不能解释为什么一个框架通过而另一个框架失败。 ..
"xUnit.net has done away with the ExpectedException attribute in favor of Assert.Throws." 来自 https://xunit.github.io/docs/comparisons.html.
结果翻转的原因是不再抛出异常所以:
MSTest:因为它使用了属性而期望异常,因此失败,因为它没有得到异常
XUnit:忽略 expect 异常属性,因为框架不使用它,因此通过,因为异常没有导致测试失败。
更改方法后不再抛出异常的原因比较复杂,但它基本上与为使用 yield 关键字的方法创建状态机有关。目前,您的 public 方法不直接使用 yield 关键字,因此它被视为普通函数,因此会在调用该方法后立即执行 null 检查并抛出异常。将 yield 关键字移动到 public 方法使其成为惰性状态机,因此它不会执行 null 检查以抛出异常,直到您开始迭代 IEnumerable。