当创建客户端时,Mocked HttpClientFactory返回null。

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

我正在尝试对一个使用了 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);
}
c# unit-testing nunit asp.net-core-3.1 nsubstitute
1个回答
2
投票

被测试的主题方法调用

 var client = _httpClientFactory.CreateClient("Movie Api");

但你将mock配置为当 CreateClient() 被调用。

httpClientFactoryMock.CreateClient().Returns(fakeHttpClient);

这意味着,当测试和 CreateClient("Movie Api") 被调用后,mock不知道该怎么做,因此返回了 无效,导致下一次调用抛出NRE

设置模拟系统,使其在被测系统被调用时,表现为预期的样子。

//...

httpClientFactoryMock.CreateClient("Movie Api").Returns(fakeHttpClient);

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