以往遇到寫測試需要部份比對物件的欄位資料,都是額外安裝91哥推薦的 Expected Objects,
https://dotblogs.com.tw/hatelove/2016/03/28/compare-object-equality-with-expected-objects
不過這陣子看文件意外發現FluentAssertions本身也有支援,這篇文章來演練一下FluentAssertion的物件部分比對功能
第一個測試: expect的欄位都可以在actual裡面找到,綠燈
[Fact]
public void Test1() {
var obj1 = new {
Username = "obj",
Age = 30
};
var obj2 = new {
Username = "obj"
};
obj1.Should().BeEquivalentTo(obj2);
}
第二個測試: expect的欄位比actual多,紅燈
[Fact]
public void Test2() {
var obj1 = new {
Username = "obj",
Age = 30
};
var obj2 = new {
Username = "obj"
};
obj2.Should().BeEquivalentTo(obj1);
}
第三個測試: expect有欄位無法在actual裡面找到,紅燈
[Fact]
public void Test3() {
var obj1 = new {
Username = "obj",
Age = 30
};
var obj2 = new {
Username = "obj",
Email = "test@test.com"
};
obj1.Should().BeEquivalentTo(obj2);
}
藉由前面三個測試,可以得到BeEquivalentTo的比對以expect為主,只要expect的欄位可以在actual裡面找到就可以成功比對,那麼問題來了,
像第三個測試的情況expect跟actual只有部分欄位有交集,在FluentAssertions怎麼處理呢
來看一下第四個測試: 綠燈!
[Fact]
public void Test4() {
var obj1 = new {
Username = "obj",
Age = 30
};
var obj2 = new {
Username = "obj",
Email = "test@test.com"
};
obj1.Should().BeEquivalentTo(obj2, options => options.ExcludingMissingMembers());
}
在BeEquivalentTo中添加options.ExcludingMissingMembers()選項可以排除掉沒有交集的欄位,這樣就可以簡單的達成部分比對。
還可以利用options.Excluding指定排除特定欄位的比對
[Fact]
public void Test5() {
var obj1 = new {
Username = "obj",
Age = 30
};
var obj2 = new {
Username = "obj",
Age = 30,
Email = "test@test.com"
};
obj1.Should().BeEquivalentTo(obj2, options => options.Excluding(o=>o.Email));
}
options還可以物件鍊一樣串起來處理複數的條件!
[Fact]
public void Test6() {
var obj1 = new {
Username = "obj",
Age = 30
};
var obj2 = new {
Username = "obj",
Age = 30,
Email = "test@test.com"
};
obj1.Should().BeEquivalentTo(obj2, options => options.Excluding(o => o.Age)
.ExcludingMissingMembers());
本來使用FluentAssertions是為了方便閱讀,看了文件之後才發現許多額外的強大支援功能
關於更多物件比對的功能,可以參考官網文件http://fluentassertions.com/documentation.html#object-graph-comparison