Assert.Empty(msgs) 和 Assert.False(msgs.Any()) 有啥区别?
Posted
技术标签:
【中文标题】Assert.Empty(msgs) 和 Assert.False(msgs.Any()) 有啥区别?【英文标题】:What is the difference between Assert.Empty(msgs) and Assert.False(msgs.Any())?Assert.Empty(msgs) 和 Assert.False(msgs.Any()) 有什么区别? 【发布时间】:2019-09-08 05:17:14 【问题描述】:我正在使用 XUnit 来测试预期为空的 Enumerable 列表的场景。
我注意到在某些情况下:
Assert.Empty(msgs);
失败;
但是
Assert.False(msgs.Any());
正在通过。
这让我有点困惑,因为我预计这是在测试同一件事。
我知道这可能是因为以下预期行为的差异:
-
Enumerable.Any()(将其定义为“确定一个序列是否包含任何元素。”)
与
-
XUnit.Empty() 中预期的空值(定义这是对空对象的测试)。
但是,我不确定到底有什么区别,因为在我看来,它实际上是在测试相同的东西。
有人能解释一下这两种不同类型的 Assert 所测试的内容的区别吗?
【问题讨论】:
您能分享重现您所见内容的代码吗? 【参考方案1】:这是Enumerable.Any
的来源(Assert.False()
只是验证它返回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();
他们似乎使用了一种非常相似的方法来检查集合中是否存在项目。我希望每种方法都有相同的结果。
如果没有详细说明您是如何使用每一个的,很难说为什么会得到不同的结果。
【讨论】:
谢谢。这些测试是在 Docker 容器中作为集成测试的一部分运行的,并且根据您指出的源代码,我已经重新检查了该环境之外的行为,并且结果中的差异没有被复制。由此我得出结论,集成设置是导致结果差异的原因。感谢您提供帮助,尽管这是一个愚蠢的问题,但这是一个很好的学习机会。【参考方案2】:这两种方法是有区别的:
.Any() 是一个 extension method,它接受一个 IEnumerable - 一个实现 IEnumerable 接口的对象,让代码遍历它以进行设置操作(如 .Any() 或 .Where())
Assert.Empty() 似乎不会检查对象是否实现了 IEnumerable,但只会在输入数据是字符串或数组时检查空集。
我的猜测是你传递的是一个 IEnumerable 对象,而不是一个数组。
要解决这个问题,您可以像以前一样使用Assert.False(msgs.Any());
,或者使用Assert.Empty(msgs.ToArray());
之类的东西
【讨论】:
【参考方案3】:msge.Any() 当 msge 不为 null 且具有一个或多个元素时返回 true,否则返回 false,因此可能有 msge 为 null 并且 Assert.Empty 在参数为 null 时失败。 致以最诚挚的问候。
【讨论】:
以上是关于Assert.Empty(msgs) 和 Assert.False(msgs.Any()) 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
找不到包 ros-melodic-humanoid-nav-msgs
ROS在rviz中实时显示轨迹(nav_msgs/Path消息的使用)