mardi 19 février 2019

Unit Tests and incapsulation

For example, I have a class, working with HttpClient

public class DomainActions : IDomainActions
{
    private readonly HttpClient _client;
    private readonly IConfiguration _configuration;

    public DomainActions(IConfiguration configuration, HttpMessageHandler httpMessageHandler)
    {
        _configuration = configuration;
        _client = new HttpClient()
        {
            BaseAddress = new Uri(_configuration.GetSection("DomainRegistration:BaseAddress").Value)
        };
        _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _configuration.GetSection("DomainRegistration:Token").Value);
    }

    public async Task<List<DomainDto>> GetDomainListAsync()
    {
        var responseMessage = await _client.GetAsync("domains");
        return await ProcessingDomainListResponseAsync(responseMessage);
    }

Then this class is used by another class:

public class AddMxRecordToRegistrator
{
    protected readonly IDomainActions domainActions;
    public AddMxRecordToRegistrator(IConfiguration configuration)
    {
        domainActions = new DomainActions(configuration);
    }

    public async Task CreateDomainRecordAsync()
    {
            await domainActions.CreateDomainRecordAsync(queueItem.DomainForRegistration.DomainName, new DomainRegistrationCore.Models.DomainRecordDto
            {
                Content = queueItem.MxRecord,
                Name = String.Empty,
                Priority = 0,
                Ttl = 3600,
                Type = DomainRecordType.MX.ToString(),
                Regions = null
            });

ok, it works fine.

Right now, I want to create unit test for AddMxRecordToRegistrator class, but I don't want to use real httpClient. How to do it? Of course, I can add one more dependency:

public class DomainActions : IDomainActions
{
    private readonly HttpClient _client;
    private readonly IConfiguration _configuration;

    public DomainActions(IConfiguration configuration, HttpMessageHandler httpMessageHandler)
    {
        _configuration = configuration;
        _client = new HttpClient(httpMessageHandler)
        {
            BaseAddress = new Uri(_configuration.GetSection("DomainRegistration:BaseAddress").Value)
        };
        _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _configuration.GetSection("DomainRegistration:Token").Value);
    }


    public DomainActions(IConfiguration configuration) : this(configuration, new HttpClientHandler())
    {
    }

    public async Task<List<DomainDto>> GetDomainListAsync()
    {
        var responseMessage = await _client.GetAsync("domains");
        return await ProcessingDomainListResponseAsync(responseMessage);
    }

then modify AddMxRecordToRegistrator class:

public class AddMxRecordToRegistrator
{
    protected readonly IDomainActions domainActions;
    public AddMxRecordToRegistrator(IConfiguration configuration, HttpMessageHandler httpMessageHandler)
    {
        domainActions = new DomainActions(configuration, httpMessageHandler);
    }

    public async Task CreateDomainRecordAsync()
    {
            await domainActions.CreateDomainRecordAsync(queueItem.DomainForRegistration.DomainName, new DomainRegistrationCore.Models.DomainRecordDto
            {
                Content = queueItem.MxRecord,
                Name = String.Empty,
                Priority = 0,
                Ttl = 3600,
                Type = DomainRecordType.MX.ToString(),
                Regions = null
            });

but then why client of AddMxRecordToRegistrator should know anything about internal detail of AddMxRecordToRegistrator (really detail of DomainActions) only because we need to create unit test? It like we violate incapsulation for unit tests. How to implement it correctly?

Aucun commentaire:

Enregistrer un commentaire