忽略具有 DeepEquals 的列表类型的 属性
Ignore property with list type with DeepEquals
我正在使用 DeepEqual 库来测试测试结果是否符合我的预期输出。
我比较简单
results.ShouldDeepEqual(expected);
但是,我不知道如何在我的列表类型
中忽略 属性
我正在深入比较的类型包含一个列表。此列表中包含的数据类型包含我想忽略的 Guid
属性 Id
以及日期。
忽略顶级属性效果很好。但是,我看不到如何忽略列表类型的属性。
为了暂时解决这个问题,我不得不自己编写一些代码来清除这些属性,但这显然不理想。
for (var i = 0; i < results.MyList.Count; i++)
{
results.MyList[i].Id = Guid.Empty;
expectedResults.MyList[i].Id = Guid.Empty;
}
我怎样才能做到这一点?
查看 DeepEqual 的源代码后,该库允许通过 IComparison
界面进行自定义比较。这样,我模拟了您需要的模型:
public class MyClass
{
public MyClass()
{
MyList = new List<MySubClass>(new[]
{
new MySubClass {Id = Guid.Parse("1".PadLeft(32, '0')), Name = "Foo"},
new MySubClass {Id = Guid.Parse("2".PadLeft(32, '0')), Name = "Bar"},
new MySubClass {Id = Guid.Parse("3".PadLeft(32, '0')), Name = "Test"},
});
}
public MyClass(params MySubClass[] subs)
{
MyList = new List<MySubClass>(subs);
}
public List<MySubClass> MyList { get; set; }
}
public class MySubClass
{
public Guid Id { get; set; }
public string Name { get; set; }
}
然后我继续创建自定义 IComparison
class:
public class MySubClassComparer : IComparison
{
public bool CanCompare(Type type1, Type type2)
{
return type1 == type2 && type1 == typeof(MySubClass);
}
public (ComparisonResult result, IComparisonContext context) Compare(IComparisonContext context, object value1, object value2)
{
if (value1 is MySubClass first && value2 is MySubClass second)
{
if (first.Name == second.Name)
{
return (ComparisonResult.Pass, context);
}
}
return (ComparisonResult.Fail, context);
}
}
这是我通过的两个单元测试:
[Fact]
public void IsDeepEqual_ShouldReturnTrue_WhenListHasSameNames()
{
// Arrange
MyClass sut = new MyClass();
MyClass parameter = new MyClass(new[]
{
new MySubClass {Id = Guid.Parse("4".PadLeft(32, '0')), Name = "Foo"},
new MySubClass {Id = Guid.Parse("5".PadLeft(32, '0')), Name = "Bar"},
new MySubClass {Id = Guid.Parse("6".PadLeft(32, '0')), Name = "Test"},
});
var comparer = new ComparisonBuilder().WithCustomComparison(new MySubClassComparer()).Create();
// Act
bool result = sut.IsDeepEqual(parameter, comparer);
// Assert
Assert.True(result);
}
[Fact]
public void IsDeepEqual_ShouldReturnFalse_WhenListHasDifferentNames()
{
// Arrange
MyClass sut = new MyClass();
MyClass parameter = new MyClass(new[]
{
new MySubClass {Id = Guid.Parse("4".PadLeft(32, '0')), Name = "Foo"},
new MySubClass {Id = Guid.Parse("5".PadLeft(32, '0')), Name = "Bar"},
new MySubClass {Id = Guid.Parse("6".PadLeft(32, '0')), Name = "Fail"},
});
var comparer = new ComparisonBuilder().WithCustomComparison(new MySubClassComparer()).Create();
// Act
bool result = sut.IsDeepEqual(parameter, comparer);
// Assert
Assert.False(result);
}
注释
此比较应忽略 Id
属性,但我不确定这是否是完成任务的最佳方法。有一个 IgnoreProperty 方法可能更适合该任务,但目前找不到让它工作的方法。
如果有人比我有更多的图书馆经验,请让我知道更好的方法,我会相应地更新我的答案。
DeepEqual 库现在使它变得非常简单。写就够了:
results.WithDeepEqual(expected).IgnoreProperty<MySubClass>(x => x.Id).Assert();
如果我们进行 Hayden 单元测试并稍微补充它们,你会得到这样的结果:
using System;
using Xunit;
using DeepEqual.Syntax;
using System.Collections.Generic;
public class MyClass
{
public List<MySubClass> MyList { get; } = new List<MySubClass>
{
new MySubClass {Id = Guid.NewGuid(), Name = "Foo"},
new MySubClass {Id = Guid.NewGuid(), Name = "Bar"},
new MySubClass {Id = Guid.NewGuid(), Name = "Test"}
};
}
public class MySubClass
{
public Guid Id { get; init; }
public string Name { get; init; }
}
public class DeepEqualTests
{
[Fact]
public void FullDeepEqualTest()
{
// Arrange
var first = new MyClass();
var second = new MyClass();
// Act
Action compassion = () => first
.ShouldDeepEqual(second);
// Assert
Assert.Throws<DeepEqualException>(compassion);
}
[Fact]
public void DeepEqualWithoutIdTest()
{
// Arrange
var first = new MyClass();
var second = new MyClass();
// Act
Action compassion = () => first
.WithDeepEqual(second)
.IgnoreProperty<MySubClass>(x => x.Id)
.Assert();
// Assert
compassion();
}
}
第一个测试是一个完整的比较,预计会出现异常。第二个测试在比较时会忽略ID字段,如果没有抛出异常则成功。两项测试 运行 成功
我正在使用 DeepEqual 库来测试测试结果是否符合我的预期输出。
我比较简单
results.ShouldDeepEqual(expected);
但是,我不知道如何在我的列表类型
中忽略 属性我正在深入比较的类型包含一个列表。此列表中包含的数据类型包含我想忽略的 Guid
属性 Id
以及日期。
忽略顶级属性效果很好。但是,我看不到如何忽略列表类型的属性。
为了暂时解决这个问题,我不得不自己编写一些代码来清除这些属性,但这显然不理想。
for (var i = 0; i < results.MyList.Count; i++)
{
results.MyList[i].Id = Guid.Empty;
expectedResults.MyList[i].Id = Guid.Empty;
}
我怎样才能做到这一点?
查看 DeepEqual 的源代码后,该库允许通过 IComparison
界面进行自定义比较。这样,我模拟了您需要的模型:
public class MyClass
{
public MyClass()
{
MyList = new List<MySubClass>(new[]
{
new MySubClass {Id = Guid.Parse("1".PadLeft(32, '0')), Name = "Foo"},
new MySubClass {Id = Guid.Parse("2".PadLeft(32, '0')), Name = "Bar"},
new MySubClass {Id = Guid.Parse("3".PadLeft(32, '0')), Name = "Test"},
});
}
public MyClass(params MySubClass[] subs)
{
MyList = new List<MySubClass>(subs);
}
public List<MySubClass> MyList { get; set; }
}
public class MySubClass
{
public Guid Id { get; set; }
public string Name { get; set; }
}
然后我继续创建自定义 IComparison
class:
public class MySubClassComparer : IComparison
{
public bool CanCompare(Type type1, Type type2)
{
return type1 == type2 && type1 == typeof(MySubClass);
}
public (ComparisonResult result, IComparisonContext context) Compare(IComparisonContext context, object value1, object value2)
{
if (value1 is MySubClass first && value2 is MySubClass second)
{
if (first.Name == second.Name)
{
return (ComparisonResult.Pass, context);
}
}
return (ComparisonResult.Fail, context);
}
}
这是我通过的两个单元测试:
[Fact]
public void IsDeepEqual_ShouldReturnTrue_WhenListHasSameNames()
{
// Arrange
MyClass sut = new MyClass();
MyClass parameter = new MyClass(new[]
{
new MySubClass {Id = Guid.Parse("4".PadLeft(32, '0')), Name = "Foo"},
new MySubClass {Id = Guid.Parse("5".PadLeft(32, '0')), Name = "Bar"},
new MySubClass {Id = Guid.Parse("6".PadLeft(32, '0')), Name = "Test"},
});
var comparer = new ComparisonBuilder().WithCustomComparison(new MySubClassComparer()).Create();
// Act
bool result = sut.IsDeepEqual(parameter, comparer);
// Assert
Assert.True(result);
}
[Fact]
public void IsDeepEqual_ShouldReturnFalse_WhenListHasDifferentNames()
{
// Arrange
MyClass sut = new MyClass();
MyClass parameter = new MyClass(new[]
{
new MySubClass {Id = Guid.Parse("4".PadLeft(32, '0')), Name = "Foo"},
new MySubClass {Id = Guid.Parse("5".PadLeft(32, '0')), Name = "Bar"},
new MySubClass {Id = Guid.Parse("6".PadLeft(32, '0')), Name = "Fail"},
});
var comparer = new ComparisonBuilder().WithCustomComparison(new MySubClassComparer()).Create();
// Act
bool result = sut.IsDeepEqual(parameter, comparer);
// Assert
Assert.False(result);
}
注释
此比较应忽略 Id
属性,但我不确定这是否是完成任务的最佳方法。有一个 IgnoreProperty 方法可能更适合该任务,但目前找不到让它工作的方法。
如果有人比我有更多的图书馆经验,请让我知道更好的方法,我会相应地更新我的答案。
DeepEqual 库现在使它变得非常简单。写就够了:
results.WithDeepEqual(expected).IgnoreProperty<MySubClass>(x => x.Id).Assert();
如果我们进行 Hayden 单元测试并稍微补充它们,你会得到这样的结果:
using System;
using Xunit;
using DeepEqual.Syntax;
using System.Collections.Generic;
public class MyClass
{
public List<MySubClass> MyList { get; } = new List<MySubClass>
{
new MySubClass {Id = Guid.NewGuid(), Name = "Foo"},
new MySubClass {Id = Guid.NewGuid(), Name = "Bar"},
new MySubClass {Id = Guid.NewGuid(), Name = "Test"}
};
}
public class MySubClass
{
public Guid Id { get; init; }
public string Name { get; init; }
}
public class DeepEqualTests
{
[Fact]
public void FullDeepEqualTest()
{
// Arrange
var first = new MyClass();
var second = new MyClass();
// Act
Action compassion = () => first
.ShouldDeepEqual(second);
// Assert
Assert.Throws<DeepEqualException>(compassion);
}
[Fact]
public void DeepEqualWithoutIdTest()
{
// Arrange
var first = new MyClass();
var second = new MyClass();
// Act
Action compassion = () => first
.WithDeepEqual(second)
.IgnoreProperty<MySubClass>(x => x.Id)
.Assert();
// Assert
compassion();
}
}
第一个测试是一个完整的比较,预计会出现异常。第二个测试在比较时会忽略ID字段,如果没有抛出异常则成功。两项测试 运行 成功