[ASP.NET] 使用 NSubstitute 驗證 Mock 物件的方法傳入參數

使用 NSubstitute 驗證 Mock 物件的方法傳入參數

在有些測試情境我們想要驗證是否有呼叫某個相依物件的方法,並且傳入了我們預期的參數,透過 NSubstitute 可以簡單的做驗證


我有一個待測物件 MyClass,相依了一個基於 IDbOperator 的類別

public class MyClass
{
    private readonly IDbOperator _dbOperator;

    public MyClass(IDbOperator dbOperator)
    {
        _dbOperator = dbOperator;
    }

    public void Action(int id)
    {
        _dbOperator.Create(new Member()
        {
            Id = id,
            Name = $"Name_{id}",
        });
    }
}

若我想要驗證當執行 Action(1) 時,_dbOperator的 Create 也會收到一個 id = 1的值,我可以這樣寫

public class MyTest
{
    [Fact]
    public void Index()
    {
        var dbOperator = Substitute.For<IDbOperator>();
        var myClass = new MyClass(dbOperator);

        myClass.Action(1);

        dbOperator.Received(1).Create(Arg.Is<Member>(r => r.Id == 1));
    }
}

若連 Name 也要驗證,可以直接加上 &&

dbOperator.Received(1).Create(Arg.Is<Member>(r => r.Id == 1 && r.Name == "Name_1"));

若 Member 的 Property 數量相當多時,這樣的寫法就不太適當了,這時候可以換個方式,直接取出整個參數來做驗證,重點會在 Arg.Do<T>()

[Fact]
public void Index()
{
    var member = default(Member);
    _dbOperator.Create(Arg.Do<Member>(r => member = r));

    _myClass.Action(1);

    _dbOperator.Received(1).Create(Arg.Any<Member>());
    member.Should().BeEquivalentTo(new
    {
        Id = 1,
        Name = "Name_1"
    });
}

每個一段時間都會忘記 Arg.Do 怎麼用,筆記起來方便快速回憶