Razor Pages .NET Core 2.1 Интеграционное тестирование после аутентификации - PullRequest
0 голосов
/ 23 октября 2018

Я ищу руководство ...

В настоящее время я пытаюсь написать несколько интеграционных тестов для приложения Razor Pages в .net core 2.1, страницы, которые я хочу протестировать,после аутентификации, но я не уверен, как лучше к ней подойти.Документы, кажется, предлагают создать CustomWebApplicationFactory, но кроме этого я немного потерял из-за того, как я могу подделать / смоделировать аутентифицированного пользователя / запрос, используя базовую аутентификацию на основе файлов cookie.

Я виделчто существует открытая проблема GitHub в отношении документов Microsoft (вот актуальная проблема GitHub ), было упомянутое решение с использованием IdentityServer4, но я просто смотрю, как это сделать, простоиспользуя проверку подлинности на основе файлов cookie.

Кто-нибудь получил какое-либо руководство, которое он может предложить?

Заранее спасибо

Мой код на данный момент:

Запуск.cs

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
        {
            services.AddDbContext<ApplicationDbContext>(options =>
            {
                options.UseMySql(connectionString);
                options.EnableSensitiveDataLogging();
            });

            services.AddLogging(builder =>
            {
                builder.AddSeq();
            });

            services.ConfigureAuthentication();
            services.ConfigureRouting();
    }
}

ConfigureAuthentication.cs

  namespace MyCarparks.Configuration.Startup
  {
      public static partial class ConfigurationExtensions
      {
          public static IServiceCollection ConfigureAuthentication(this IServiceCollection services)
          {
              services.AddIdentity<MyCarparksUser, IdentityRole>(cfg =>
              {
                  //cfg.SignIn.RequireConfirmedEmail = true;
              })
              .AddDefaultUI()
              .AddDefaultTokenProviders()
              .AddEntityFrameworkStores<ApplicationDbContext>();

              services.ConfigureApplicationCookie(options =>
              {
                  options.LoginPath = $"/Identity/Account/Login";
                  options.LogoutPath = $"/Identity/Account/Logout";
                  options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
              });

              services.AddMvc()
                  .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
                  .AddRazorPagesOptions(options =>
              {
                    options.AllowAreas = true;
                    options.Conventions.AuthorizeAreaFolder("Identity", "/Account/Manage");
                    options.Conventions.AuthorizeAreaPage("Identity", "/Account/Logout");

                    options.Conventions.AuthorizeFolder("/Sites");
                });

            return services;
        }
    }
}

Интеграционные тесты

PageTests.cs

namespace MyCarparks.Web.IntegrationTests
{
    public class PageTests : IClassFixture<CustomWebApplicationFactory<Startup>>
    {
        private readonly CustomWebApplicationFactory<Startup> factory;

        public PageTests(CustomWebApplicationFactory<Startup> webApplicationFactory)
        {
            factory = webApplicationFactory;
        }


    [Fact]
    public async Task SitesReturnsSuccessAndCorrectContentTypeAndSummary()
    {
        var siteId = Guid.NewGuid();
        var site = new Site { Id = siteId, Address = "Test site address" };
        var mockSite = new Mock<ISitesRepository>();
        mockSite.Setup(s => s.GetSiteById(It.IsAny<Guid>())).ReturnsAsync(site);

        // Arrange
        var client = factory.CreateClient();

        // Act
        var response = await client.GetAsync("http://localhost:44318/sites/sitedetails?siteId=" + siteId);

        // Assert
        response.EnsureSuccessStatusCode();

        response.Content.Headers.ContentType.ToString()
            .Should().Be("text/html; charset=utf-8");

        var responseString = await response.Content.ReadAsStringAsync();
        responseString.Should().Contain("Site Details - MyCarparks");
    }

    public class CustomWebApplicationFactory<TStartup> : WebApplicationFactory<Startup>
    {
        protected override void ConfigureWebHost(IWebHostBuilder builder)
        {
            builder.UseStartup<Startup>();
        }
    }
}

1 Ответ

0 голосов
/ 24 октября 2018

Для реализации вашего требования вы можете попробовать код ниже, который создает клиента с файлами cookie аутентификации.

    public class CustomWebApplicationFactory<TEntryPoint> : WebApplicationFactory<TEntryPoint> where TEntryPoint : class
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureServices(services =>
        {

        });
        base.ConfigureWebHost(builder);
    }
    public new HttpClient CreateClient()
    {
        var cookieContainer = new CookieContainer();
        var uri = new Uri("https://localhost:44344/Identity/Account/Login");
        var httpClientHandler = new HttpClientHandler
        {
            CookieContainer = cookieContainer
        };
        HttpClient httpClient = new HttpClient(httpClientHandler);
        var verificationToken = GetVerificationToken(httpClient, "https://localhost:44344/Identity/Account/Login");
        var contentToSend = new FormUrlEncodedContent(new[]
                {
                            new KeyValuePair<string, string>("Email", "test@outlook.com"),
                            new KeyValuePair<string, string>("Password", "1qaz@WSX"),
                            new KeyValuePair<string, string>("__RequestVerificationToken", verificationToken),
                        });
        var response = httpClient.PostAsync("https://localhost:44344/Identity/Account/Login", contentToSend).Result;
        var cookies = cookieContainer.GetCookies(new Uri("https://localhost:44344/Identity/Account/Login"));
        cookieContainer.Add(cookies);
        var client = new HttpClient(httpClientHandler);
        return client;
    }
    private string GetVerificationToken(HttpClient client, string url)
    {
        HttpResponseMessage response = client.GetAsync(url).Result;
        var verificationToken =response.Content.ReadAsStringAsync().Result;
        if (verificationToken != null && verificationToken.Length > 0)
        {
            verificationToken = verificationToken.Substring(verificationToken.IndexOf("__RequestVerificationToken"));
            verificationToken = verificationToken.Substring(verificationToken.IndexOf("value=\"") + 7);
            verificationToken = verificationToken.Substring(0, verificationToken.IndexOf("\""));
        }
        return verificationToken;
    }
}
...