Как сделать интеграционный тест при использовании PrincipalContext (Windows аутентификация)? - PullRequest
0 голосов
/ 21 января 2020

У меня есть intr anet asp core 3.0 MVC веб-приложение с windows аутентификацией. В Views / Shared / _Layout я вызываю ViewCompent, чтобы получить имя и фамилию текущего пользователя следующим методом:

    public Task<string> getNameAsync()
    {
        return Task.Run<string>(() =>
        {
            string name = GetNameInSession();
            if (name == null || name == "")
            {
                PrincipalContext pc = new PrincipalContext(ContextType.Domain);
                UserPrincipal user = UserPrincipal.FindByIdentity(pc, User.Identity.Name);
                name = user.GivenName + " " + user.Surname;
                SetNameInSession(name);
            }
            return name;
        });
    }

В настоящее время я пытаюсь написать интеграционный тест для своего приложения, но каждый раз, когда он обращается к методу getNameAsyn c (), он выбрасывает нулевое исключение, потому что ContextType.Domain имеет значение null.

Я прочитал в Интернете и нашел способы использования пользовательских идентификаторов для своего теста, так что теперь User. Identity.Name возвращает все, что я хочу, но я не могу найти способ смоделировать или определить пользовательский ContextType.Domain или смоделировать PrincipalContext ... Я подумал, что, возможно, я мог бы использовать ClaimsPrincipal.FindFirstValue (ClaimType.GivenName) вместо использования PrincipalContext но он всегда возвращает ноль.

Вот мой интеграционный тест:

public class BrowseControllerTest : IClassFixture<CustomApplicationFactory<Startup>>
    {
        protected readonly HttpClient _client;

        public BrowseControllerTest(CustomApplicationFactory<Startup> factory)
        {
            _client = factory.CreateClient();
        }

        [Theory]
        [InlineData(1)]
        [InlineData(2)]
        public async Task ReturnDomain(int value)
        {
            var response = await _client.GetAsync("/Browse/Domain/"+value);
            response.EnsureSuccessStatusCode();
        }
    }

Мой CustomApplicationFactory, который позволяет мне использовать тестовую базу данных и идентификацию пользователя:

public class CustomApplicationFactory<TStartup>
        : WebApplicationFactory<TStartup> where TStartup : class
    {
        protected override void ConfigureWebHost(IWebHostBuilder builder)
        {
            builder.ConfigureServices(services =>
            {
                // Remove the app's ApplicationDbContext registration.
                var descriptor = services.SingleOrDefault(
                    d => d.ServiceType ==
                        typeof(DbContextOptions<My_DBContext>));

                if (descriptor != null)
                {
                    services.Remove(descriptor);
                }

                // Add ApplicationDbContext using an in-memory database for testing.
                services.AddDbContext<BRG_DistributionContext>(options =>
                {
                    options.UseInMemoryDatabase("InMemoryDbForTesting");
                });

                services.AddAuthentication(o =>
               {
                   o.DefaultScheme = "TestScheme";
               }).AddCustomAuthentication("TestScheme", "My custom authentication scheme", o => { });

                // Build the service provider.
                var sp = services.BuildServiceProvider();

                using (var scope = sp.CreateScope())
                {
                    var scopedServices = scope.ServiceProvider;
                    var db = scopedServices.GetRequiredService<BRG_DistributionContext>();
                    var logger = scopedServices
                        .GetRequiredService<ILogger<CustomApplicationFactory<TStartup>>>();

                    // Ensure the database is created.
                    db.Database.EnsureCreated();

                    try
                    {
                        // Seed the database with test data.
                        Utilities.InitializeDbForTests(db);
                    }
                    catch (Exception ex)
                    {
                        logger.LogError(ex, "An error occurred seeding the " +
                            "database with test messages. Error: {Message}", ex.Message);
                    }
                }
            });
        }

Итак, мой вопрос: как я могу издеваться / определять пользовательский ContextType.Domain или PrincipalContext? Если это невозможно, как я могу получить имя и фамилию текущего пользователя, используя утверждения, если FindFirstValue (ClaimTypes.GivenName) возвращает ноль?

...