[C#] 單元測試套件 FluentAssertions

  • 57
  • 0
  • 2024-11-27

之前寫單元測試時,都是使用 91 介紹的 ExpectedObjects 這個套件來作物件的比對

最近發現同事使用 FluentAssertions 套件寫單元測試

想紀錄一下區別

在我的測試專案中,安裝 FluentAssertions 套件 

 

我有一個 NumberResponse 物件,使用 Should().Be做物件比對

故意將 property 的順序寫的不一樣

    [Test]
    public void FluentAssertions_Be()
    {
        var actual = new NumberResponse
        {
            ErrorCode = 1,
            Message = "none",
            ResultData = 666
        };
        
        actual.Should().Be(new NumberResponse
        {
            Message = "none",
            ErrorCode = 1,
            ResultData = 666
        });
    }

會得到

使用 Should().BeEquivalentTo做物件的比對

一樣 property 的順序寫的不一樣,但測試是可以通過的

    [Test]
    public void FluentAssertions_BeEquivalentTo()
    {
        var actual = new NumberResponse
        {
            ErrorCode = 1,
            Message = "none",
            ResultData = 666
        };
        
        actual.Should().BeEquivalentTo(new NumberResponse
        {
            Message = "none",
            ErrorCode = 1,
            ResultData = 666
        });
    }

使用 ExpectedObjects 套件來做物件比對的寫法

也是順序寫的不一樣,測試是可以通過的

    [Test]
    public void ExpectedObjects()
    {
        var expected = new NumberResponse
        {
            ErrorCode = 1,
            Message = "none",
            ResultData = 666
        };
        
        expected.ToExpectedObject().ShouldEqual(new NumberResponse
        {
            Message = "none",
            ErrorCode = 1,
            ResultData = 666
        });
    }

如果物件和預期的不一樣,看到的錯誤訊息會長這樣

要 debug 的話,都不會太困難看懂

另外 FluentAssertions 可以排除不想比較的 property,寫法也蠻易讀的

    [Test]
    public void FluentAssertions_BeEquivalentTo_And_Excluding() 
    {
        var actual = new NumberResponse
        {
            ErrorCode = 1,
            Message = "error",
            ResultData = 666
        };
        
        actual.Should().BeEquivalentTo(new NumberResponse
        {
            Message = "none",
            ErrorCode = 1,
            ResultData = 666
        }, options => options.Excluding(o=>o.Message));
    }

畢竟平常在維護 legacy code 的時候,物件一大包,不一定整個物件我都需要做比對

接下來想要順手紀錄一下各式各樣 exception 的測試寫法

使用原生的 Assert.Throws 

    [Test]
    public void Exception()
    {
        Assert.Throws(Is.TypeOf<Exception>(),
            () => throw new Exception("something error")).Message.Should().Be("something error");
    }

使用 FluentAssertions

    [Test]
    public void FluentAssertions_Exception()
    {
        var result = new Func<object>(() => throw new Exception("something error"));

        result.Should().Throw<Exception>()
            .Where(x => x.Message == "something error");
    }

FluentAssertions的寫法和語意相較 Assert.Throws好看與好讀


91 介紹 ExpectedObjects

[UnitTest] 使用 Fluent Assertions 增加單元測試碼可讀性

FluentAssertions官方文件