Assert.AreEqual 如何确定两个通用 IEnumerables 之间的相等性? [英] How does Assert.AreEqual determine equality between two generic IEnumerables?

查看:28
本文介绍了Assert.AreEqual 如何确定两个通用 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.AreEquals?

推荐答案

Assert.AreEqual 将比较手头的两个对象.IEnumerables 本身就是类型,并提供一种机制来迭代某些集合……但它们实际上不是那个集合.您的原始比较比较了两个 IEnumerables,这是一个有效的比较……但不是您需要的.您需要比较两个 IEnumerable 打算枚举什么.

Assert.AreEqual is going to compare the two objects at hand. IEnumerables 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 IEnumerables, which is a valid comparison...but not what you needed. You needed to compare what the two IEnumerables 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆