使用模拟对 IHttpClientFactory 调用进行单元测试

时间:2021-02-13 12:06:43

标签: c# api unit-testing mocking

我需要使用 GetAsync 调用对 IHttpClientFactory 调用进行单元测试。但是,除非我输入实际的 Url,否则我无法弄清楚如何模拟 repo。这是我的代码

public class SchemeAccess : IScheme
{
    private readonly IConfiguration configuration;

    private readonly IHttpClientFactory httpClientFactory;

    private readonly string baseUrl;

    private readonly ILogger<SchemeAccess> logger;

    public SchemeAccessLayer(IConfiguration configuration, IHttpClientFactory httpClientFactory, ILogger<BillingAccessLayer> logger)
    {
        this.configuration = configuration;

        this.httpClientFactory = httpClientFactory;

        this.baseUrl = this.configuration["Api:BaseUrl"];

        this.logger = logger;
    }

    public async Task<List<SchemesEntity>> GetSchemes(string dateFrom, string dateTo)
    {
        string relative = $" GetSchemes?StartDate={dateFrom}&EndDate={dateTo}";

        this.logger.LogInformation(
            $"GET statement received from {this.baseUrl} {relative} {DateTime.Now}.");

        var httpClient = this.httpClientFactory.CreateClient();

        var response = await httpClient.GetAsync(this.baseUrl + relative);

        if (response.StatusCode != HttpStatusCode.OK)
        {
            this.logger.LogError(
                $"{this.baseUrl} {relative} {response.StatusCode}: {response.Content.ReadAsStringAsync()}");
        }

        var content = await response.Content.ReadAsStringAsync();

        return JsonConvert.DeserializeObject<List<SchemesEntity>>(content);
    }
}

public interface IScheme
{
    public Task<List<SchemesEntity>> GetSchemes(string dateFrom, string dateTo);
}

public class SchemeService
{
    private readonly IScheme objScheme;

    public SchemeService(IScheme scheme)
    {
        this.objScheme = scheme;
    }

    public Task<List<SchemesEntity>> GetSchemesList(string dateFrom, string dateTo)
    {
        return this.objScheme.GetSchemes(dateFrom, dateTo);
    }
}

    protected void GetFilteredSchemes(string dateFrom, string dateTo)
    {
    var schemeService =  new SchemeService();
        schemes = Task.Run(async () => await schemeService.GetSchemeList(dateFrom, dateTo)).Result;
    }


    [Fact]
    public async Task GetSchemes_ReturnsFilteredList()
    {
        // Arrange
        var startDate = DateTime.Today.AddDays(-60).ToString();
        var endDate = DateTime.Today.ToString();

        var schemeEntity = new List<SchemeEntity>()
        {
            new Scheme()
            {
                Id = "Guid.NewGuid()",
                Name = "Scheme1",
            DateStart = new DateTime(2020, 02, 01),
                DateEnd = new DateTime(2021, 02, 12)
            },             
            new Scheme()
            {
                 Id = "Guid.NewGuid()",
                Name = "Scheme2",
            DateStart = new DateTime(2021, 01, 01),
                DateEnd = new DateTime(2021, 02, 12)
            }
        };
         var mockConfSection = new Mock<IConfigurationSection>();
        mockConfSection.SetupGet(m => m[It.Is<string>(s => s == "Api")]).Returns("BaseUrl");

        configurationMock = new Mock<IConfiguration>();
        configurationMock.Setup(a => a.GetSection(It.Is<string>(s => s == "Api"))).Returns(mockConfSection.Object);

        loggerMock = new Mock<ILogger<SchemeAccess>>();

        httpClientFactoryMock = new Mock<IHttpClientFactory>();

        var schemeAccess = new SchemeAccessLayer(configurationMock.Object, httpClientFactoryMock.Object, loggerMock.Object);

        schemeMock = new Mock<IScheme>();

        this.schemeMock.Setup(a => a.GetScheme(startDate, endDate))
            .Returns(() => Task.FromResult<List<SchemeEntity>>(schemeEntity));

        schemeMock.Setup(x => x.GetSchemeList(startDate, endDate)).ReturnsAsync(schemeEntity);

        var schemeService = new SchemeService(schemeMock.Object);

        // Act
        var result = await schemeService.GetSchemeList(startDate, endDate);

        // Assert
        result.Count.Should().Be(1);
        result.Should().BeOfType<List<SchemeEntity>>();
    }

上面的测试在 result.Count.Should().Be(1) 行上失败了,bacaase 没有过滤 repo。 我如何为 GetSchemes 调用创建一个虚假的存储库,使其不会失败。

入口点来自protected void GetFilteredSchemes(string dateFrom, string dateTo)

我需要重新构建代码吗? 请帮忙

谢谢

0 个答案:

没有答案