You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用NSubstitute在C#中测试GraphQLHttpClient

用NUnit和NSubstitute模拟GraphQLHttpClient的简便方法

方式一:通过自定义HttpMessageHandler创建真实的GraphQLHttpClient实例

这种方式贴近真实请求流程,能验证请求构造是否正确,步骤如下:

  1. 完善自定义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);
    }
}
  1. 在测试中创建实例并验证:
[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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 23:55:18