带有ExpectedException的XUnit和MSTest返回不同的结果

我有一个正在使用yield return的项目,并且不理解为什么在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分配返回对象并尝试对其进行迭代来使它们都通过,但这不能解释为什么一个框架通过而另一个框架失败了…

解决方法:

“ xUnit.net取消了ExpectedException属性,转而使用Assert.Throws.”从https://xunit.github.io/docs/comparisons.html开始.

结果翻转的原因是不再抛出异常,因此:

MSTest:期望异常,因为它使用属性,因此失败,因为它没有获取异常

XUnit:因为框架未使用Expect异常属性,所以它会忽略它,因此会通过,因为异常不会导致测试失败,因此会通过.

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

上一篇:使用 xUnit 编写 ASP.NET Core 单元测试


下一篇:c#-Moq usermanager缺少IUserEmailStore