Ollpej
Ollpej

Reputation: 27

UnitTest cant find endpoint

Using xUnit 2.4.1 to test the Api always fails to find Controller

When I create a WebApplicationFactory and pass Startup file as parameter the HTTP Client from WebApplicationFactory.CreatVlient() always returns 404 for Get requests.

Testing a .Net Core Api that uses MVC.

The CommonContext is an internal class that sets the connection.

The Configfile reads correctly
The Connectionstring to DB is correct
The Endpoint is not called correctly and therefore never hits the controller.

Class that inherits 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>();
        }
    }

Unit Test

  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());
        }
    }

Controller is in the project im testing

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

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

    }

Startup

   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();

            }
        }
    }

Upvotes: 0

Views: 591

Answers (1)

Marco
Marco

Reputation: 23945

According to the attribute routing in your controller, the action method has the url api/Test/GetExample: [HttpGet("GetExample")], yet in your in test you are testing for CreateExample:

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

So I guess, your test is correct in returning a 404. That route simply will not resolve to any existing action method. I suggest you change your theory to [InlineData("api/Test/GetExample")]

Upvotes: 1

Related Questions