利用FluentAssertions做部分比對或排除特定欄位比對

以往遇到寫測試需要部份比對物件的欄位資料,都是額外安裝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