断言IEnumerables

时间:2009-02-13 11:53:17

标签: c# unit-testing

由于我们公司没有使用单元测试,我正在教自己对我自己的代码进行单元测试。 我正在使用标准的.net测试框架进行一些非常基本的单元测试。

我的方法返回IEnumerable<string>,我想测试它的输出。 所以我创建了一个IEnumerable<string>,希望对它进行测试。 我以为我记得那里有Assert.ArePartsEqual或类似的东西,但我似乎无法找到它。

简而言之,我如何测试两个IEnumerable<string>是否包含相同的字符串?

4 个答案:

答案 0 :(得分:25)

我不知道您指的是哪个“标准.net测试框架”,但如果是Visual Studio Team System Unit测试内容,您可以使用CollectionAssert

您的测试将是这样的:

CollectionAssert.AreEqual(ExpectedList, ActualList, "...");

更新:我忘了CollectionAssert需要一个ICollection接口,所以你必须调用ActualList.ToList()才能让它编译。返回IEnumerable是一件好事,所以不要只为测试改变它。

答案 1 :(得分:12)

您需要SequenceEqual()扩展方法(LINQ):

    string[] x = { "abc", "def", "ghi" };
    List<string> y = new List<string>() { "abc", "def", "ghi" };

    bool isTrue = x.SequenceEqual(y);

或只是:

   bool isTrue = x.SequenceEqual(new[] {"abc","def","ghi"});

(如果长度不同,或者任何项目不同,则返回false)

答案 2 :(得分:5)

我有一个例子,我用于“在60分钟内实现对象的LINQ”谈话。

它也在我的MoreLinq项目中。在这里尝试过它,它包裹得非常糟糕。只需grab from Github ...

答案 3 :(得分:0)

使用 NUnit 3+ 'constraint' 断言有一种简单但不明显的方法来做到这一点:

#!/usr/bin/env python3
import subprocess
import shlex

def main():
    cmd = 'bash -c "for i in $(seq 1 5);do echo $i; sleep 1; done;"'
    print(cmd)
    p = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, universal_newlines=True)
    for line in p.stdout:
        print(f"file_name: {line.strip()}", flush=True)
    p.wait()

if __name__ == "__main__":
    main()

这将为您提供与其他答案中提到的 linq 相同的内容:

Assert.That(result, Is.EqualTo(expected).AsCollection, "My failure message");

但是 Assert.That(result.SequenceEqual(expected), "My failure message"); 版本会告诉您第一个区别在哪里,以及长度是否不同。

https://docs.nunit.org/articles/nunit/writing-tests/constraints/EqualConstraint.html#comparing-arrays-collections-and-ienumerables