如何使用NSubstitute在C#中测试GraphQLHttpClient
用NUnit和NSubstitute模拟GraphQLHttpClient的简便方法
方式一:通过自定义HttpMessageHandler创建真实的GraphQLHttpClient实例
这种方式贴近真实请求流程,能验证请求构造是否正确,步骤如下:
- 完善自定义Handler,支持灵活设置响应:
public class MockGraphQLHandler : HttpClientHandler { public HttpResponseMessage MockResponse { get; set; } protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { // 可选:可根据request内容(如GraphQL查询语句)返回不同响应 // var requestContent = await request.Content.ReadAsStringAsync(); // if (requestContent.Contains("targetQuery")) { ... } return await Task.FromResult(MockResponse); } }
- 在测试中创建实例并验证:
[Test] public async Task Test_GraphQL_Query_Response() { // 准备模拟的GraphQL响应内容 var mockResponseContent = new StringContent( "{\"data\": {\"user\": {\"id\": 1, \"name\": \"TestUser\"}}}", Encoding.UTF8, "application/json" ); var mockHttpResponse = new HttpResponseMessage(HttpStatusCode.OK) { Content = mockResponseContent }; // 初始化自定义Handler并设置响应 var mockHandler = new MockGraphQLHandler { MockResponse = mockHttpResponse }; // 创建HttpClient并关联Handler var httpClient = new HttpClient(mockHandler); // 实例化GraphQLHttpClient(可按需传入GraphQLHttpClientOptions) var graphQlClient = new GraphQLHttpClient( "https://dummy-endpoint.com/graphql", new NewtonsoftJsonSerializer(), httpClient ); // 执行测试:调用GraphQLHttpClient的方法 var queryRequest = new GraphQLRequest { Query = "query { user { id name } }" }; var response = await graphQlClient.SendQueryAsync<UserQueryResponse>(queryRequest); // 断言结果符合预期 Assert.Multiple(() => { Assert.That(response.Data.User.Id, Is.EqualTo(1)); Assert.That(response.Data.User.Name, Is.EqualTo("TestUser")); }); } // 定义对应的响应模型 public class UserQueryResponse { public User User { get; set; } } public class User { public int Id { get; set; } public string Name { get; set; } }
方式二:直接用NSubstitute模拟GraphQLHttpClient方法
如果只需快速验证业务逻辑,无需关注请求构造细节,可直接模拟核心方法:
[Test] public async Task Test_Service_With_Mocked_GraphQLClient() { // 模拟GraphQLHttpClient实例 var mockGraphQlClient = Substitute.For<GraphQLHttpClient>(); // 设置模拟的SendQueryAsync返回值 var mockGraphResponse = new GraphQLResponse<UserQueryResponse> { Data = new UserQueryResponse { User = new User { Id = 2, Name = "MockedUser" } } }; mockGraphQlClient.SendQueryAsync<UserQueryResponse>( Arg.Any<GraphQLRequest>(), Arg.Any<CancellationToken>() ).Returns(Task.FromResult(mockGraphResponse)); // 将模拟客户端注入业务服务 var userService = new UserService(mockGraphQlClient); var fetchedUser = await userService.GetUserById(2); // 断言业务逻辑结果正确 Assert.That(fetchedUser.Name, Is.EqualTo("MockedUser")); } // 示例业务服务 public class UserService { private readonly GraphQLHttpClient _graphQlClient; public UserService(GraphQLHttpClient graphQlClient) { _graphQlClient = graphQlClient; } public async Task<User> GetUserById(int userId) { var request = new GraphQLRequest { Query = $"query {{ user(id: {userId}) {{ id name }} }}" }; var response = await _graphQlClient.SendQueryAsync<UserQueryResponse>(request); return response.Data.User; } }
两种方式对比
- 方式一更适合需要验证请求构造正确性的场景(如检查查询语句、请求头是否合规);
- 方式二更适合快速测试业务逻辑流程,无需关注底层HTTP请求细节。
内容的提问来源于stack exchange,提问作者arquex
相关产品推荐
相关产品推荐

