C# Prime Factors Kata 中的单元测试失败

Unit test failure in C# Prime Factors Kata

资深程序员,C# 新手。刚开始使用 VS2012 和内置测试框架进行 Prime Factors Kata。在第一次测试中,预期和实际匹配,但它被标记为失败。任何人都可以解释为什么,更重要的是解决方法是什么?

using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace PrimeFactorsKata
{
    [TestClass]
    public class UnitTest1
    {
        private static List<int> ExpectedList()
        {
            return new List<int>();
        }

        [TestMethod]
        public void TestOne()
        {
            Assert.AreEqual(ExpectedList(), PrimeFactorGenerator.Generate(1));
        }
    }

    class PrimeFactorGenerator
    {
        public static List<int> Generate(int n)
        {
            return new List<int>();
        }
    }
}

输出:

Assert.AreEqual failed. 
Expected:<System.Collections.Generic.List`1[System.Int32]>. 
Actual:<System.Collections.Generic.List`1[System.Int32]>. 

   at PrimeFactorsTest.UnitTest1.TestOne() in UnitTest1.cs: line 17

C# 中引用类型的默认相等性是实例相等性 - 您的断言失败,因为两个参数不是 List<T> 的同一个实例。 MSTest 中没有开箱即用的 Assert 序列相等性,但您可以使用 Enumerable.SequenceEqualAssert.IsTrue 之类的东西来达到相同的效果,例如

[TestMethod]
public void TestOne()
{
    Assert.IsTrue(ExpectedList().SequenceEqual(PrimeFactorGenerator.Generate(1));
}

编辑:

显然在 MSTest 中 集合断言(感谢 @juharr),这会将您的测试简化为

[TestMethod]
public void TestOne()
{
    CollectionAsssert.AreEquivalent(ExpectedList(), PrimeFactorGenerator.Generate(1));
}

您正在尝试比较两个不同的对象引用。

Assert.AreEqual(ExpectedList(), PrimeFactorGenerator.Generate(1));

这是在调用 ExpectedList(),然后是在调用 PrimeFactorGenerator.Generate(1)。每个调用都创建并返回对 new 对象的引用(因为您有 new 关键字)。 Assert.AreEqual() 然后比较明显不相同的引用。

了解引用和对象内容之间的区别很重要。引用是指向对象值(内容)的指针。

你需要做的是遍历两个列表并比较内容(假设你在其中插入了一些数据,在你的示例中它们是空的,但这段代码仍然有效):

var l1 = ExpectedList();
var l2 = PrimeFactorGenerator.Generate(1);

Assert.AreEqual(l1.Count, l2.Count);

if (l1.Count > 0) //Make sure you have data
    for (int i = 0, i < l1.Count, i++)
        Assert.AreEqual(l1[i], l2[i]);

正如其他人提到的,您正在比较每个列表的引用,它们是不同的。要比较内容,您可以使用 CollectionAssert.AreEqual

[TestMethod]
public void TestOne()
{
    CollectionAssert.AreEqual(ExpectedList(), PrimeFactorGenerator.Generate(1));
}

您还可以在 CollectionAssert like AreEquivalent

上查看其他方法

每一个都有覆盖,允许您传递 IComparer 以确定您希望如何比较集合中的项目。