【问题标题】:Assert.Contains doesn't find the object in a listAssert.Contains 在列表中找不到对象
【发布时间】:2022-01-23 01:17:26
【问题描述】:

我是单元测试的新手,我想测试一个方法,该方法获取一个字符串数组,其中包含一些名称,如“John,Doe”,然后它用“,”分割名称并填充@列表987654326@ 带有这些名称,所以我希望在返回的列表中有一个名字为 John 和姓氏 Doe 的 PersonModel,但 Assert.Contains 方法不断抛出此错误:

Assert.Contains() 失败

未找到:PersonModel { FirstName = "John", FullName = "John Doe", 姓氏 = "Doe" }

在值:列表 [PersonModel { FirstName = "John", FullName = "John Doe", LastName = "Doe" }, PersonModel { FirstName = “Jane”,FullName = “Jane Doe”,LastName = “Doe”}]

这是DataAccess类中将姓名转换为人员列表的方法:

public static List<PersonModel> ConvertCsvNamesToPeopleList(string[] csvContent)
{
    List<PersonModel> output = new List<PersonModel>();

    foreach (string line in csvContent)
    {
        string[] data = line.Split(',');
        output.Add(new PersonModel { FirstName = data[0], LastName = data[1] });
    }

    return output;
}

这是测试:

[Fact]
public void ConvertCsvNamesToPeopleList_ValidCsvContent_ShouldWork()
{
    string[] csvContent = { "John,Doe", "Jane,Doe" };

    var expectedPerson = new PersonModel { FirstName = "John", LastName = "Doe" };
    var expectedPerson2 = new PersonModel { FirstName = "Jane", LastName = "Doe" };
    var actual = DataAccess.ConvertCsvNamesToPeopleList(csvContent);

    Assert.Contains(expectedPerson, actual);
    Assert.Contains(expectedPerson2, actual);
}

人物模型:

public class PersonModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string FullName => $"{ FirstName } { LastName }";
}

【问题讨论】:

  • PersonModel 是否覆盖 Equals
  • @Mureinik 不,它没有
  • PersonModelclass,对吗?不是recordstruct?你遇到的是reference vs value equality。对象具有相同的,但在内存中不是同一个对象,因此不相等。
  • 看看Best way to compare two complex objects。有多种方法可以按值比较类实例。正如@Mureinik 指出的那样,最简单的方法是override Equals
  • 别担心!值得注意的是,如果您使用 record 的实例(在 C# 9.0 或更高版本中可用),您可以免费获得此功能:Try it out on .NET Fiddle

标签: c# unit-testing xunit


【解决方案1】:

Contains 依赖于找到两个相等的对象,所以你应该重写它的Equals 方法。为了更好地衡量,你也应该重写它的 GetHashCode 方法,这样你就可以在需要时将它用作字典的键:

public override bool Equals(object obj)
{
    return obj is PersonModel model &&
           FirstName == model.FirstName &&
           LastName == model.LastName;
}

public override int GetHashCode()
{
    return HashCode.Combine(FirstName, LastName);
}

【讨论】:

  • 要覆盖GetHashCode,我在任何地方都找不到HashCode,我尝试了System.HashCode,但它不再存在,我应该如何使用它?
  • @Genesys 如果您没有可用的HashCode,您可以通过以下几种方式自己实现GetHashCodestackoverflow.com/q/263400/2422776
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-02
  • 1970-01-01
  • 2018-12-31
  • 1970-01-01
  • 1970-01-01
  • 2011-07-04
  • 1970-01-01
相关资源
最近更新 更多