Assert.Empty(msgs) 和 Assert.False(msgs.Any()) 有什么区别?

What is the difference between Assert.Empty(msgs) and Assert.False(msgs.Any())?

我正在使用 XUnit 测试需要空 Enumerable 列表的场景。

我注意到在某些情况下:

但是

这让我有点困惑,因为我预计这是在测试同一件事。

我知道这可能是因为预期行为的差异:

  1. Enumerable.Any()(定义为 "Determines whether a sequence contains any elements.")

  1. XUnit.Empty() 中预期为空(定义这是对空对象的测试)。

但是,我不确定到底有什么不同,因为在我看来,本质上是在测试同一件事。

有人可以解释一下在这两种不同类型的断言中测试的内容的区别吗?

这是 Enumerable.Any 的来源(Assert.False() 只是验证了这个 returns false。):

public static bool Any<TSource>(this IEnumerable<TSource> source) {
    if (source == null) throw Error.ArgumentNull("source");
    using (IEnumerator<TSource> e = source.GetEnumerator()) {
        if (e.MoveNext()) return true;
    }
    return false;
}

这是来自 xUnit 的 Assert.Empty 的来源:

public static void Empty(IEnumerable collection)
{
    Assert.GuardArgumentNotNull("collection", collection);

    var enumerator = collection.GetEnumerator();
    try
    {
        if (enumerator.MoveNext())
            throw new EmptyException(collection);
    }
    finally
    {
        (enumerator as IDisposable)?.Dispose();
    }
}

他们似乎使用了一种非常相似的方法来检查集合中是否存在项目。我希望每种方法都能得到相同的结果。

如果没有关于如何使用每一个的更多详细信息,很难说出为什么会得到不同的结果。

这两种方法有区别:

.Any() 是一个 extension method which takes an IEnumerable - 一个实现 IEnumerable 接口的对象,让代码遍历它以进行设置操作,(如 .Any() 或 .Where())

Assert.Empty() 似乎不检查对象是否实现 IEnumerable,但仅在输入数据为字符串或数组时检查空集。

我猜你传递的是一个 IEnumerable 对象,而不是一个数组。

要解决这个问题,您可以像以前一样使用 Assert.False(msgs.Any());,或者使用 Assert.Empty(msgs.ToArray());

之类的东西

msge.Any() returns 当 msge 不为空且具有一个或多个元素时为真,否则为假,因此可能 msge 为空且 Assert.Empty 在参数为空时失败。
谨致问候。