模拟 IRestClient.ExecuteAsync 结果上的空数据

问题描述 投票:0回答:1

我有一个使用 RestSharp (110.2.0) 的方法,我想对其进行单元测试,但遇到困难。

示例方法:

private IRestClient _restClient;

public async Task<string> GetToken()
{
    var pw = await _vault.GetValue("pw");
    var un = await _vault.GetValue("un");
    
    var request = new RestRequest(new Uri("login"));
    request.AddJsonBody(new 
    {
        Username = un,
        Password = pw
    });
    
    var response = await _restClient.ExecutePostAsync<string>(request);
    return response.Data;
}

样品测试:

private AutoMocker _mocker;

[Fact]
public async Task SomeTest()
{
    _mocker.GetMock<IRestClient>()
        .Setup(m => m.ExecuteAsync(It.Is<RestRequest>(r => r.Resource == "login"), It.IsAny<CancellationToken>()))
        .ReturnsASync(new RestResponse
            {
                StatusCode = HttpStatusCode.OK, ResponseStatus = ResponseStatus.Completed,
IsSuccessStatusCode = true,
Content = "authToken",
            });
            
    var result = await _uut.GetToken();
    
    Assert.Equal("authToken", result);
}

对于这种情况,请忽略我本质上是在测试我的模拟是否返回我想要的内容。实际代码更全面,http 内容只是该过程中的一小步(但现在是拦截器)。

按原样运行,我收到空引用异常。使用这个问题的答案,我对测试进行了以下更改:

[Fact]
public async Task SomeTest()
{
    var serializerConfig = new SerializerConfig();
    serializerConfig.UseDefaultSerializers();
    
    _mocker.GetMock<IRestClient>()
        .Setup(m => m.Serializers)
        .Returns(new RestSerializers(serializerConfig));
    
    ...rest of test code

这解决了空引用异常,但

response.Data
始终为空。我可以在
content
中看到预期值,但在
Data
中看不到。

我尝试更改模拟设置以返回此值:

.ReturnsAsync(new RestResponse<string>(new RestRequest())
{
    StatusCode = HttpStatusCode.OK, ResponseStatus = ResponseStatus.Completed,
    IsSuccessStatusCode = true,
    Content = "authToken",
    Data = "authToken"
});

但这并不能改变什么。我还在嘲笑的回复中添加了

ContentType = "application/json; charset=utf-8"
,但再次没有成功。

我知道RestSharp Docs的建议,但目前对我来说不切实际。

c# moq restsharp
1个回答
0
投票

根据 RestSharp Docs 的建议推断,我将测试修改为如下所示:

public class TestClass
{
    public TestClass()
    {
        _mocker = new AutoMocker();
        _mockHttp = new MockHttpMessageHandler(); //from RichardSzalay.MockHttp
        _mocker.Use<IRestClient>(new RestClient(new RestClientOptions("http://localhost"){ ConfigureMessageHandler = _ => _mockHttp }));
        _uut = _mocker.CreateInstance<ClassToTest>();
    }
    
[Fact]
public async Task SomeTest()
{
    _mockHttp
        .When("*/REST/Login")
        .Respond("application/json", JsonConvert.SerializeObject("authToken"));
            
    var result = await _uut.GetToken();
    
    Assert.Equal("authToken", result);
}

这很有效,而且实际上比我预期的实现要干净得多。最初我担心在将 MockHttpMessageHandler 分配给 IRestClient 后我将无法对其进行本质上的修改,但事实并非如此。

© www.soinside.com 2019 - 2024. All rights reserved.