3

我怎样才能对这种方法进行单元测试

public static ICollection<Person> SelectPersonByCountry(string Country, LinkedList<Person> personList)  
    {  
        ICollection<Person> selectedPerson = new List<Person>();  
          if (Country != String.Empty)   
        {  
            foreach (Person item in personList)  
            {  
                  if (item.Country.ToUpper().Equals(Country.ToUpper()))
                  {  
                    selectedPerson.Add(item);  
                }  
            }  
        }  
        else  
        {  
            // do something  
            return null;  
        }  
        return selectedPerson;  

方法 CollectionAssert.AreEqual() 需要 2 个参数 ICollection 和 ICollection 但我有通用 ICollection。我需要做什么?

public void TestMethod1()
    {
        string country = "Ukraine";

        LinkedList<lab1.Person> personList = new LinkedList<lab1.Person>();
        personList.AddFirst(new Person("Dasda", "Sasha", "Ukraine", "23131", "Ukrainian"));
        personList.AddFirst(new Person("Sasa", "OLeg", "Ukraine", "23131", "Ukrainian"));
        personList.AddFirst(new Person("Popa", "Sveta", "Ukraine", "23131", "Ukrainian"));
        personList.AddFirst(new Person("Bezik", "Vitya", "Ukraine", "23131", "Ukrainian"));
        personList.AddFirst(new Person("Hoi", "Oleg", "Ukraine", "23131", "Ukrainian"));
        ICollection<Person> expected = new LinkedList<Person>();
        expected.Add(new Person("Dasda", "Sasha", "Ukraine", "23131", "Ukrainian"));
        expected.Add(new Person("Sasa", "OLeg", "Ukraine", "23131", "Ukrainian"));
        expected.Add(new Person("Popa", "Sveta", "Ukraine", "23131", "Ukrainian"));
        expected.Add(new Person("Bezik", "Vitya", "Ukraine", "23131", "Ukrainian"));
        expected.Add(new Person("Hoi", "Oleg", "Ukraine", "23131", "Ukrainian"));


        ICollection expected1 = (ICollection)expected;

        ICollection actual = (ICollection)lab1.Person.SelectPersonByCountry(country, personList);



        CollectionAssert.AreEqual(expected1, actual );



    }

我的方法必须像预期的那样返回集合,因为我所有的人都来自“乌克兰”,但测试没有通过..

4

4 回答 4

3

方法 CollectionAssert.AreEqual() 需要 2 个参数 ICollection 和 ICollection 但我有通用 ICollection。我需要做什么?

大多数泛型集合也实现了非泛型ICollection接口,因此无论如何您都可以传递泛型集合。

ICollection actual = (ICollection)SelectPersonByCountry(country, personList);
ICollection expected = new[] { person1, person2 };

CollectionAssert.AreEqual(actual, expected);
于 2013-10-10T07:38:21.153 回答
2

这实际上有两个(潜在的)原因:

首先,列表的顺序。要将元素添加到 personList 中,请使用 addFirst,它将元素添加到列表中。要将元素添加到预期中,请使用 Add,它将元素附加到列表中。但是,您以相同的顺序通过人员。因此,expected 和 personList 的顺序颠倒了。CollectionsAssert.AreEquals 的文档指出

集合必须具有相同的计数,并且以相同的顺序包含完全相同的对象。

其次,Person 不能重新定义 Equals。如果是这种情况,C#默认引用相等,这意味着什么

new Person("Dasda", "Sasha", "Ukraine", "23131", "Ukrainian")
  .Equals(new Person("Dasda", "Sasha", "Ukraine", "23131", "Ukrainian")) == false

有三种方法可以解决此问题:

  1. 在您的 Person 类中覆盖 Equals(和 HashCode)
  2. 创建 Person 实例一次,并在期望列表和 personList 列表中使用它们。顺便说一句,此解决方案还将降低拼写错误的风险。但这会使您的测试依赖于需要返回相同实例的实现。
  3. 使用 CollectionAssert.AreEqual(IEnumerable, IEnumerable, IComparer) 在 Person 类之外定义相等关系。请记住,您应该为 IComparer 编写测试!
于 2013-10-10T08:29:52.810 回答
1

是的,虽然我从未使用过 CollectionAssert.AreEqual,但我很确定这将与如何执行集合中每个元素的底层对象比较有关。AreEqual doco状态;

如果它们的值相等,则元素相等,而不是如果它们引用同一个对象。默认情况下,使用Equals比较元素的值。

我的猜测是您需要确保您的 Person 对象实现 Equals 方法以允许对象比较。上述 equals 方法的链接;

静态 Equals(Object, Object) 方法指示两个对象 objA 和 objB 是否相等。它还使您能够测试值为 null 的对象是否相等。它比较 objA 和 objB 是否相等,如下所示:

它确定两个对象是否代表相同的对象引用。

如果是,则该方法返回 true。此测试等效于调用 ReferenceEquals 方法。此外,如果 objA 和 objB 都为 null,则该方法返回 true。它确定 objA 或 objB 是否为空。如果是,则返回 false。如果这两个对象不代表同一个对象引用且都不为 null,则调用 objA.Equals(objB) 并返回结果。这意味着如果 objA 覆盖 Object.Equals(Object) 方法,则调用此覆盖。

请参阅Equals文档页面上的示例,了解如何实现这一点以确保一个 person 对象实际上与您期望的相同。

编辑:如果你不想在你的 Person 对象中覆盖 Equals,那么可以在你定义国家变量的地方创建一次,然后将相同的 Person 记录添加到你的 LinkedList 和你的 ICollection 中。这样,参考可能是相同的......我想。

于 2013-10-10T08:19:42.293 回答
0

谢谢你。我在 Person 中覆盖了我的 Equals 方法,它现在可以工作了。我像这样被覆盖,也许这很糟糕,但你可以改进

  public override bool Equals(object objA)
  {
    Person person = objA as Person;
    if (person == null) return false;
    return (person.FirstName == this.FirstName && person.LastName == this.LastName && person.Language == this.Language && person.PersonId == this.PersonId)
  }
于 2013-10-13T13:18:58.643 回答