具有链接方法的模拟 SDK 客户端

Mocking SDK client which has chained methods

我需要如下单元测试 Test1() 并且必须模拟 msgraph-sdk 创建具有 http 调用的事件。
我在嘲笑 Request()A​​ddAsync( ) 方法,但在 Act.
上得到了空值 通过模拟对 CreateAsync 进行单元测试的正确方法是什么?

public interface IApiClient
{
    Task<Event> CreateAsync(EventItem eventItem);
}

public class ApiClient : IApiClient
{
    private readonly IGraphServiceClient _graphServiceClient;


    public ApiClient(IGraphServiceClient graphServiceClient)
    {
        _graphServiceClient = graphServiceClient;
    }

    public async Task<Event> CreateAsync(EventItem eventItem)
    {
        var item = new Event
        {
            Subject = eventItem.Subject
        };
        return await _graphServiceClient.Users[eventItem.UserInfo.Id].Events
            .Request()
            .AddAsync(item);
    }

}

public class ApiClientTest
{
    private Mock<IGraphServiceClient> _graphServiceClientMock;
    private IApiClient _apiClient;
    private Mock<IUserEventsCollectionRequest> _mockUserEventsCollectionRequest;
    private EventItem _eventItem;

    [SetUp]
    public async System.Threading.Tasks.Task SetupAsync()
    {
        var x = new Microsoft.Graph.Event()
        {
            Subject = "123"
        };

        _graphServiceClientMock = new Mock<IGraphServiceClient>();
        _mockUserEventsCollectionRequest = new Mock<IUserEventsCollectionRequest>();
        _apiClient = new IApiClient(_graphServiceClientMock.Object);

        _graphServiceClientMock.Setup(g => g.Users[_eventItem.UserInfo.Id].Events
                               .Request())
                               .Returns(
        _mockUserEventsCollectionRequest.Setup(g => g.AddAsync(x))
                               .ReturnsAsync(new Event { Id = "asaasaS" });

    }

    [Test]
    public async Task Test1()
    {
        // Act
        var newEvent = await _apiClient.CreateAsync(_eventItem);
        // Assert
        Assert.NotNull(newEvent);
        Assert.AreEqual("asaasaS", newEvent.Id);
    }
}   

我在嘲笑 Request()A​​ddAsync( ) 方法,但在 Act 上得到了空值。
通过模拟对 CreateAsync 进行单元测试的正确方法是什么?

你有很多嘲笑来测试这个,所以也许你应该问问自己是否值得。如果答案是肯定的,那么这里有一个例子,你可以如何做到这一点(我将所有内容都放入 Test1 方法并跳过 [SetUp] 方法以获得更好的可见性)。

public class ApiClientTest
{
    [Test]
    public async Task Test1()
    {
        // Arrange
        Event @event = new Event { Subject = "Subject", Id = "123" };
        EventItem eventItem = new EventItem { Subject = @event.Subject, UserInfo = new UserInfo { Id = @event.Id } };

        Mock<IUserEventsCollectionRequest> mockUserEventsCollectionRequest = new Mock<IUserEventsCollectionRequest>();
        mockUserEventsCollectionRequest.Setup(x => x.AddAsync(It.IsAny<Event>())).ReturnsAsync(@event);

        Mock<IUserEventsCollectionRequestBuilder> mockUserEventsCollectionRequestBuilder = new Mock<IUserEventsCollectionRequestBuilder>();
        mockUserEventsCollectionRequestBuilder.Setup(x => x.Request()).Returns(mockUserEventsCollectionRequest.Object);

        Mock<IUserRequestBuilder> userRequestBuilder = new Mock<IUserRequestBuilder>();
        userRequestBuilder.Setup(x => x.Events).Returns(mockUserEventsCollectionRequestBuilder.Object);

        Mock<IGraphServiceClient> graphServiceClient = new Mock<IGraphServiceClient>();
        graphServiceClient.Setup(x => x.Users[It.IsAny<string>()]).Returns(userRequestBuilder.Object);

        IApiClient apiClient = new ApiClient(graphServiceClient.Object);

        // Act
        Event newEvent = await apiClient.CreateAsync(eventItem);

        // Assert
        Assert.NotNull(newEvent);
        Assert.AreEqual(@event.Id, newEvent.Id);
        Assert.AreEqual(@event.Subject, newEvent.Subject);
    }
}