Как издеваться над AuthenticationContext.AcquireTokenAsyn c в модульном тесте C# - PullRequest
0 голосов
/ 17 июня 2020

У меня есть метод под названием GenerateJWTToken() для генерации токена на предъявителя. Он использует AuthenticationContext Однако AuthenticationContext не имеет интерфейса. Как имитировать это в модульном тесте?

Вот код:

 private async Task<string> GenerateJWTToken()
    {
        var instance = _configuration["AzureAd:Instance"];
        var tenantId = _configuration["AzureAd:TenantId"];
        var clientId = _configuration["AzureAd:ClientId"];
        var clientSecret = _configuration.GetSection("appsecret").Value;
        var resource = _configuration["AzureAd:Resource"];

        var authority = string.Format("{0}{1}", instance, tenantId);
        ClientCredential credential = new ClientCredential(clientId, clientSecret);
        AuthenticationContext authContext = new AuthenticationContext(authority, false);
        var result = await authContext.AcquireTokenAsync(resource, credential);
        return result.AccessToken;
    }

  public async Task<HttpResponseMessage> GetResponseFromService(string userToken)
        {
            string endpoint = _configuration.GetSection("Service:Endpoint").Value;

            var httpRequestMessage = new HttpRequestMessage()
            {
                Method = HttpMethod.Get,
                RequestUri = new Uri(endpoint)
            };

            var jwtToken = await GenerateJWTToken();
            httpRequestMessage.Headers.Add("Authorization", "Bearer " + jwtToken);
            httpRequestMessage.Headers.Add("token", userToken);

            HttpResponseMessage httpResponseMessage = await _rpsRequest.ExecuteAsync(() => httpRequestMessage, maxRetry);

            return httpResponseMessage 
        }

Предположим, нам нужно написать модульный тест на GetResponseFromService(), может ли кто-нибудь показать мне, как имитировать AuthenticationContext.AcquireTokenAsync порция? Спасибо!

Ответы [ 2 ]

2 голосов
/ 18 июня 2020

Вы вообще не используете метод Dependency Injection в GenerateJWTToken - вы создаете объекты ClientCredential и AuthenticationContext внутри GenerateJWTToken - и поэтому это сложно для модульного тестирования. И также нарушает принцип инверсии зависимостей от SOLID, даже если у вас нет «реальных интерфейсов».

Передайте экземпляры ClientCredential и AuthenticationContext как параметры GenerateJWTToken и GenerateJWTToken, что позволяет вам хорошо имитировать и тестировать модули . Внедряйте зависимости в этот код вместо создания новых объектов.

ОБНОВЛЕНИЕ
Теперь я вижу, что вы, вероятно, правы, здесь нет другого выбора, кроме некоторого «развлечения» с Moq или классом-оболочкой.
Главный вопрос - почему вы используете старый, немного устаревший ADAL, когда там действительно поддерживается библиотека MSAL? MSAL поддерживает интерфейсы et c. https://docs.microsoft.com/pl-pl/azure/active-directory/develop/msal-net-migration#differences -between-adal-and-msal-apps

Из github:

Эта библиотека, ADAL для. NET, больше не будет получить новые улучшения функций. Вместо этого используйте новую библиотеку MSAL для. NET.

https://github.com/AzureAD/microsoft-authentication-library-for-dotnet

1 голос
/ 19 июня 2020

После некоторого исследования я понял, что ADAL нельзя тестировать, и мы не тестируем сам ADAL. Поэтому я извлек GenerateJWTToken в новый класс, имеющий свой интерфейс. И используйте внедрение зависимостей для класса, у которого есть метод GetResponseFromService().

...