3

我有一个使用收益返回的项目,但不明白为什么在 MSTest 通过时 XUnit 未能在我的单元测试中捕获异常。

这是我的虚拟代码。

奇怪的是,如果我采用我的私有方法 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 分配返回对象并尝试迭代它来让它们都通过,但这并不能解释为什么一个框架通过而另一个框架失败......

4

1 回答 1

4

“xUnit.net 已经取消了 ExpectedException 属性以支持 Assert.Throws。” 来自https://xunit.github.io/docs/comparisons.html

结果翻转的原因是不再抛出异常所以:

MSTest:预期异常,因为它使用该属性,因此失败,因为它没有得到异常

XUnit:忽略期望异常属性,因为框架不使用它,因此通过,因为异常没有导致测试失败。

如果您更改方法,则不再引发异常的原因更为复杂,但它基本上与为使用 yield 关键字的方法创建状态机有关。当前,您的公共方法不直接使用 yield 关键字,因此它被视为普通函数,因此执行 null 检查并在调用该方法时立即抛出异常。将 yield 关键字移动到公共方法使其成为惰性状态机,因此在您开始迭代 IEnumerable 之前,它不会执行 null 检查以引发异常。

于 2017-01-18T21:49:12.893 回答