我有一个使用 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的建议,但目前对我来说不切实际。
根据 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 后我将无法对其进行本质上的修改,但事实并非如此。