我正在尝试对一个使用了 IHttpClientFactory
与Nunit和NSubstitute进行嘲讽。
我想测试的服务是这样的
public class Movies : IMovies
{
private readonly IHttpClientFactory _httpClientFactory;
public Movies(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public async Task<MovieCollection> GetPopularMovies(int PageNumber = 1)
{
// Get an instance of HttpClient from the factpry that we registered
// in Startup.cs
var client = _httpClientFactory.CreateClient("Movie Api");
// Call the API & wait for response.
// If the API call fails, call it again according to the re-try policy
// specified in Startup.cs
var result =
await client.GetAsync($"movie/popular?api_key=<the_api_key>language=en-US&page={PageNumber}");
if (result.IsSuccessStatusCode)
{
// Read all of the response and deserialise it into an instace of
var content = await result.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<MovieCollection>(content);
}
return null;
}
}
当我运行测试时,我得到一个错误信息,说是
System.NullReferenceException 。在MovieApi.Services.Movies.GetPopularMovies(Int......),对象引用没有被设置为对象的实例。
这是我正在运行的测试,只有当我把关键字 "MovieApi.Services.Movies.GetPopularMovies(Int...) "放入时才会出现错误。await
一行
var result = await service.GetPopularMovies(1);
检查下面的测试代码。
[Test]
public async Task GetPopular_WhenCalled_ReturnOK()
{
//arrange
var moviecollection = new MovieCollection();
var httpClientFactoryMock = Substitute.For<IHttpClientFactory>();
var fakeHttpMessageHandler = new FakeHttpMessageHandler(new HttpResponseMessage() {
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonConvert.SerializeObject(moviecollection), Encoding.UTF8, "application/json")
});
var fakeHttpClient = new HttpClient(fakeHttpMessageHandler);
httpClientFactoryMock.CreateClient().Returns(fakeHttpClient);
// Act
var service = new Movies(httpClientFactoryMock);
var result = await service.GetPopularMovies(1);
//assert
Assert.IsNotNull(result);
}
被测试的主题方法调用
var client = _httpClientFactory.CreateClient("Movie Api");
但你将mock配置为当 CreateClient()
被调用。
httpClientFactoryMock.CreateClient().Returns(fakeHttpClient);
这意味着,当测试和 CreateClient("Movie Api")
被调用后,mock不知道该怎么做,因此返回了 无效,导致下一次调用抛出NRE
设置模拟系统,使其在被测系统被调用时,表现为预期的样子。
//...
httpClientFactoryMock.CreateClient("Movie Api").Returns(fakeHttpClient);
//...