Assert.AreEqual 如何确定两个通用 IEnumerables 之间的相等性? [英] How does Assert.AreEqual determine equality between two generic IEnumerables?
问题描述
我有一个单元测试来检查一个方法是否返回正确的IEnumerable
.该方法使用 yield return
构建可枚举.它是可枚举的类如下:
I have a unit test to check whether a method returns the correct IEnumerable
. The method builds the enumerable using yield return
. The class that it is an enumerable of is below:
enum TokenType
{
NUMBER,
COMMAND,
ARITHMETIC,
}
internal class Token
{
public TokenType type { get; set; }
public string text { get; set; }
public static bool operator == (Token lh, Token rh) { return (lh.type == rh.type) && (lh.text == rh.text); }
public static bool operator != (Token lh, Token rh) { return !(lh == rh); }
public override int GetHashCode()
{
return text.GetHashCode() % type.GetHashCode();
}
public override bool Equals(object obj)
{
return this == (Token)obj;
}
}
这是该方法的相关部分:
This is the relevant part of the method:
foreach (var lookup in REGEX_MAPPING)
{
if (lookup.re.IsMatch(s))
{
yield return new Token { type = lookup.type, text = s };
break;
}
}
如果我把这个方法的结果存入actual
,再做一个可枚举的expected
,然后这样比较...
If I store the result of this method in actual
, make another enumerable expected
, and compare them like this...
Assert.AreEqual(expected, actual);
...,断言失败.
我为 IEnumerable
编写了一个扩展方法,类似于 Python 的 zip
函数(它将两个 IEnumerables 组合成一组对)并尝试了这个:
I wrote an extension method for IEnumerable
that is similar to Python's zip
function (it combines two IEnumerables into a set of pairs) and tried this:
foreach(Token[] t in expected.zip(actual))
{
Assert.AreEqual(t[0], t[1]);
}
成功了!那么这两个 Assert.AreEqual
有什么区别呢?
It worked! So what is the difference between these two Assert.AreEqual
s?
推荐答案
Assert.AreEqual
将比较手头的两个对象.IEnumerable
s 本身就是类型,并提供一种机制来迭代某些集合……但它们实际上不是那个集合.您的原始比较比较了两个 IEnumerable
s,这是一个有效的比较……但不是您需要的.您需要比较两个 IEnumerable
打算枚举什么.
Assert.AreEqual
is going to compare the two objects at hand. IEnumerable
s are types in and of themselves, and provide a mechanism to iterate over some collection...but they are not actually that collection. Your original comparison compared two IEnumerable
s, which is a valid comparison...but not what you needed. You needed to compare what the two IEnumerable
s were intended to enumerate.
以下是我比较两个可枚举的方法:
Here is how I compare two enumerables:
Assert.AreEqual(t1.Count(), t2.Count());
IEnumerator<Token> e1 = t1.GetEnumerator();
IEnumerator<Token> e2 = t2.GetEnumerator();
while (e1.MoveNext() && e2.MoveNext())
{
Assert.AreEqual(e1.Current, e2.Current);
}
我不确定上面的代码是否比您的 .Zip
方法少,但它是最简单的.
I am not sure whether the above is less code than your .Zip
method, but it is about as simple as it gets.
这篇关于Assert.AreEqual 如何确定两个通用 IEnumerables 之间的相等性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!