具有链接方法的模拟 SDK 客户端
Mocking SDK client which has chained methods
我需要如下单元测试 Test1() 并且必须模拟 msgraph-sdk 创建具有 http 调用的事件。
我在嘲笑 Request() 和 AddAsync( ) 方法,但在 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() 和 AddAsync( ) 方法,但在 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);
}
}
我需要如下单元测试 Test1() 并且必须模拟 msgraph-sdk 创建具有 http 调用的事件。
我在嘲笑 Request() 和 AddAsync( ) 方法,但在 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() 和 AddAsync( ) 方法,但在 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);
}
}