Tom*_*ise 12 .net collections unit-testing autofixture semantic-comparison
我们编写了一个如下所示的测试.此测试要求我们Equal为CodeTableItem-class 创建了en -overload :
ICollection<CodeTableItem> expectedValutaList = new List<CodeTableItem>();
expectedValutaList.Add(new CodeTableItem("DKK", "DKK"));
expectedValutaList.Add(new CodeTableItem("EUR", "EUR"));
RepoDac target = new RepoDac();
var actual = target.GetValutaKd();
CollectionAssert.AreEqual(expectedValutaList.ToList(),actual.ToList());
Run Code Online (Sandbox Code Playgroud)
测试工作正常,但是对Equality函数有一个不幸的依赖,这意味着如果我CodeTableItem用一个字段扩展-class,并忘记扩展Equals-function,单元测试仍然会运行绿色,尽管我们不测试所有字段.我们希望避免这种Equality污染(参见测试特定平等),这种污染只是为了符合测试而编写的.
我们尝试过使用OfLikeness,并以这种方式重写了测试:
ICollection<CodeTableItem> expectedValutaList = new List<CodeTableItem>();
expectedValutaList.Add(new CodeTableItem("DKK", "DKK"));
expectedValutaList.Add(new CodeTableItem("EUR", "EUR"));
var expectedValutaListWithLikeness =
expectedValutaList.AsSource().OfLikeness<List<CodeTableItem>>();
RepoDac target = new RepoDac();
ICollection<CodeTableItem> actual;
actual = target.GetValutaKd();
expectedValutaListWithLikeness.ShouldEqual(actual.ToList());
Run Code Online (Sandbox Code Playgroud)
但测试失败是因为Capacity不相等.我编写了多次运行反射的代码,并且通常最终实现了忽略字段的重载.有没有办法用OfLikeness或忽略某些字段ShouldEqual?或者还有其他方法可以解决这个问题吗?
Mar*_*ann 12
为什么你不想这样做
我不认为从任何List<T>事情中创造一种与你想要它做的相似.据我了解,您想比较两个列表的内容.这与比较两个列表不一样......
考虑Likeness的作用:它比较属性值.有什么属性List<T>?
他们是
正如Nikos Baxevanis在他的回答中指出的那样,你可以使用Without方法忽略Capacity属性的值,但这意味着只剩下Count属性.
换句话说,如果你这样做,这个:
expectedValutaListWithLikeness.ShouldEqual(actual.ToList());
Run Code Online (Sandbox Code Playgroud)
在功能上等同于:
Assert.AreEqual(expected.Count, actual.Count)
Run Code Online (Sandbox Code Playgroud)
换句话说,列表可能具有完全不同的数据,但如果只有每个列表具有相同数量的元素,则测试仍将通过.这可能不是你想要的......
你应该做什么
您可以使用"相似性"将每个元素相互比较.这样的事情应该有效:
var expectedValutaList = new List<CodeTableItem>();
expectedValutaList.Add(new CodeTableItem("DKK", "DKK"));
expectedValutaList.Add(new CodeTableItem("EUR", "EUR"));
var expectedValutaListWithLikeness = from cti in expectedValutaList
select cti
.AsSource()
.OfLikeness<CodeTableItem>();
var target = new RepoDac();
var actual = target.GetValutaKd();
Assert.IsTrue(expectedValutaListWithLikeness.Cast<object>().SequenceEqual(
actual.Cast<object>()));
Run Code Online (Sandbox Code Playgroud)
您也可以使用CollectionAssert作为断言,但是自从我上次使用MSTest以来已经这么多年了,我不记得那个方法的怪癖......
只需添加.Without(x => x.Capacity)和Likeness实例将Capacity在比较值时忽略该属性.
var expectedValutaListWithLikeness =
expectedValutaList.AsSource().OfLikeness<List<CodeTableItem>>()
.Without(x => x.Capacity);
Run Code Online (Sandbox Code Playgroud)
更新:
正如Mark Seemann在他的回答中指出的那样,你可能想要的是将每个元素相互比较.这是一种略微不同的方式,允许您执行非常灵活的比较.
假设RepoDac类返回类似于:
public class RepoDac
{
public ICollection<CodeTableItem> GetValutaKd()
{
return new[]
{
new CodeTableItem("DKK", "DKK"),
new CodeTableItem("EUR", "EUR")
};
}
}
Run Code Online (Sandbox Code Playgroud)
对于每个实例,expectedValutaList您可以创建一个使用Likeness覆盖Equals的动态代理:
var object1 = new CodeTableItem("DKK", "DKK1")
.AsSource().OfLikeness<CodeTableItem>()
.Without(x => x.Property2)
.CreateProxy();
var object2 = new CodeTableItem("EUR2", "EUR")
.AsSource().OfLikeness<CodeTableItem>()
.Without(x => x.Property1)
.CreateProxy();
Run Code Online (Sandbox Code Playgroud)
注意object1和object2如何具有不同的动态生成的Equals.(第一个忽略Property2而第二个忽略Property1.)
以下测试通过:
var expected = new List<CodeTableItem>();
expected.Add(object1);
expected.Add(object2);
var target = new RepoDac();
var actual = target.GetValutaKd();
Assert.IsTrue(expected.SequenceEqual(actual));
Run Code Online (Sandbox Code Playgroud)
注意:
需要从expected包含动态生成的代理(覆盖Equals)的实例开始.
您可以在此处找到有关此功能的更多信息.
| 归档时间: |
|
| 查看次数: |
2836 次 |
| 最近记录: |