UnitTest не может найти конечную точку - PullRequest
0 голосов
/ 25 апреля 2019

При использовании xUnit 2.4.1 для тестирования API всегда не удается найти контроллер

Когда я создаю WebApplicationFactory и передаю файл запуска в качестве параметра, HTTP-клиент из WebApplicationFactory.CreatVlient() всегда возвращает 404 для запросов Get.

Тестирование .Net Core Api, использующего MVC.

CommonContext - это внутренний класс, который устанавливает соединение.

Configfile правильно читает
* Connectionstring в БД является правильным
Конечная точка не вызывается правильно и поэтому никогда не попадает в контроллер.

Класс, который наследует WebApplocationFactory

    public class WebApiTestFactory<TStartup>
        : WebApplicationFactory<TStartup> where TStartup: class
    {

        protected override IWebHostBuilder CreateWebHostBuilder()
        {
            var builder = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddEnvironmentVariables();

            var configValues = new Dictionary<string, string>
            {
                {"RunStatus", "Test"},
            };
            builder.AddInMemoryCollection(configValues);

            return WebHost.CreateDefaultBuilder()
                .UseConfiguration(builder.Build())
                .UseUrls("http://localhost:53976/")
                .UseSetting("applicationUrl", "http://localhost:53976/")
                .UseStartup<Else.WebApi.Core.Startup>();
        }
    }

Модульный тест

  public class TestControllerTest : IClassFixture<WebApiTestFactory<Startup>>
    {
        private readonly WebApiTestFactory<Startup> _factory;

        public TestControllerTest(WebApiTestFactory<Startup> factory)
        {

            _factory = factory;

        }

        [Theory]
        [InlineData("api/Test/GetExample")]
        public async Task Create(string url)
        {

            // Arrange
            var clientOptions = new WebApplicationFactoryClientOptions();
            clientOptions.BaseAddress = new Uri("http://localhost:53976");
            var client = _factory.CreateClient(clientOptions);

            // Act
            var response = await client.GetAsync(url);

            // Assert
            response.EnsureSuccessStatusCode(); // Status Code 200-299
            Assert.Equal("text/html; charset=utf-8",
                response.Content.Headers.ContentType.ToString());
        }
    }

Контроллер в проекте, я тестирую

    [ApiController]
    [Route("api/Test")]
    public class TestController : Controller
    {

        [HttpGet("GetExample")]
        public ActionResult GetExample()
        {
            return Ok();
        }

    }

Запуск

   public class Startup
    {
        public Startup(IConfiguration configuration, IHostingEnvironment env)
        {

            HostingEnvironment = env;

            Configuration = configuration;

            EwBootstrapper.BootstrapElsewareServices();
        }

        public IConfiguration Configuration { get; }
        public IHostingEnvironment HostingEnvironment { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {



            if (Configuration["RunStatus"] != "Test")
            {
                services.AddTransient<AuthenticationTokens>();
                services.AddTransient<IPasswordValidator, PasswordValidator>();
                services.AddTransient<IUserRepository, UserRepository>();

                services.AddMvc();

                services.AddScoped(_ =>
           new CommonContext(Configuration.GetConnectionString("DbConnection")));

                services.AddSwaggerDocumentation();

                services
                    .AddAuthentication(JwtBearerDefaults.AuthenticationScheme) // Configure authentication (JWT bearer)
                    .AddJwtBearer(jwtOpt => // Configure JWT bearer
                    {
                        jwtOpt.TokenValidationParameters = AuthenticationTokens.GetValidationParameters();
                    });
            }
            else
            {

                //services.AddMvcCore().AddJsonFormatters();
                services.AddScoped(_ =>
           new CommonContext(Configuration.GetConnectionString("DbTestConnection")));

            }
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app)
        {

            if (Configuration["RunStatus"] != "Test")
            {
                app.UseSwaggerDocumentation();

                app.UseSwagger();
                app.UseSwaggerUI(c =>
                {
                    c.SwaggerEndpoint("/swagger/v1/swagger.json", "API");
                });
                app.UseMiddleware<ApiLoggerMiddleware>();
                app.UseMvc(builder => builder.MapRoute("Default", "api/{controller}/{action=Get}/{id?}")); // No default values for controller or action

                app.UseDefaultFiles(); // Enable default documents ( "/" => "/index.html")
                app.UseStaticFiles(); // Static files under wwwroot
                app.UseAuthentication();


            }

            if (HostingEnvironment.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();

            }
        }
    }

1 Ответ

1 голос
/ 25 апреля 2019

Согласно атрибуту маршрутизации в вашем контроллере, метод действия имеет URL-адрес api/Test/GetExample: [HttpGet("GetExample")], но в тесте вы тестируете на CreateExample:

[InlineData("api/Test/CreateExample")]

Итак, ядумаю, ваш тест верен при возврате 404. Этот маршрут просто не будет преобразован в какой-либо существующий метод действия.Я предлагаю вам изменить свою теорию на [InlineData("api/Test/GetExample")]

...