0

I am trying integration tests with XUnit. I can access the endpoints that have been assigned on MapGet but to not actions inside controllers. I get a NotFound error. I am running the application on an API project with ApplicationFactory : WebApplicationFactory but all requests that I make with Factory.Client return NotFound. Is there any definition needed in integration tests in order to be able to send requests to controllers?

Test projects code:

        private ApplicationFactory Factory { get; }

        public AccountsControllerTests(ITestOutputHelper output)
        {
            Factory = new ApplicationFactory(output);
        }
        [Fact]
        public async Task ListBalancesTest()
        {
            var client = Factory.CreateClient(new WebApplicationFactoryClientOptions(){AllowAutoRedirect = false});;

            var resp = await client.GetAsync($"api/v1/test/get");
            //!!!!!!! resp.StatusCode is HttpStatusCode.NotFound !!!!!!!


            var mapgetResp= await client.GetAsync($"/test");
            //!!!!!!! mapgetResp is Working !!!!!!!
            Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode);
        }

API Code:

    [ApiController]
    [Route("api/v1/test")]
    public class TestController : ControllerBase
    {
        [HttpGet("get")]
        public async Task<ActionResult> Get()
        {
            return await Task.FromResult(Ok("Response from test"));
        }
    }

ApplicationFactory Code:

public class ApplicationFactory : WebApplicationFactory<TestStartup>
    {
        public ApplicationFactory(ITestOutputHelper testOutput = null)
        {
            _testOutput = testOutput;
        }

        protected override IWebHostBuilder CreateWebHostBuilder()
        {
            var builder = WebHost
                .CreateDefaultBuilder()
                .UseEnvironment("Development")
                .UseStartup<TestStartup>()
                .UseSerilog();

            if (_testOutput != null)
            {
                builder = builder.ConfigureLogging(logging =>
                {
                    logging.Services.TryAddEnumerable(
                        ServiceDescriptor.Singleton<ILoggerProvider>(new TestOutputHelperLoggerProvider(_testOutput)));
                });
            }

            return builder;
        }

protected override void ConfigureWebHost(IWebHostBuilder builder)
        {
            builder.UseContentRoot(".");

            builder.ConfigureServices(services =>
            {/...../}
         }
  }

Startup:

app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                endpoints.MapGet("/test", async context =>
                {
                    await context.Response.WriteAsync(@$"Test value from MapGet");
                });
                /..../
            });
FBY
  • 39
  • 5
  • I think the path was not found. See : https://stackoverflow.com/questions/14011026/the-controller-for-path-was-not-found-or-does-not-implement-icontroller?force_isolation=true – jdweng Aug 10 '22 at 14:14
  • I work with one culture and I do not have Area support but I only have this problem when I run or debug tests. I go directly via controller and I can go to those endpoints via postman or other. @jdweng – FBY Aug 10 '22 at 18:49
  • When you work are you inside a c# application? – jdweng Aug 10 '22 at 21:05
  • I have two applications one is .net 6 api project(it is testable) and the second on is test project which is on XUnit – FBY Aug 10 '22 at 21:11
  • What type of machines are you on. Issue is not with c# but the interfaces with the operating system. What version of Net/Core are you using? What errors are you getting? What is the response Status? – jdweng Aug 10 '22 at 21:19
  • both of them are .net 6 projects. My machine is windows 11 x64. Actually I do not get an error but the problem is that when I run the project with dotnet run there are endpoint which I can access via postman but when I debug and run tests for these endpoints I get response status of NOT FOUND. you can above see my start up on above shared codes. For example for actions of controlle which I defined inside MapGet in startup I can run tests for this one. But for others which I did not make MapGet they return NotFound on test run. – FBY Aug 10 '22 at 21:29
  • WindowsLinux is an operating system and not a machine. Windows/linux can run on a PC or phones. the URL are not being found with due to a credentials issue. Postman is working which indicates it is possible for the connection to complete. You are getting a response which indicates the connection is completing and then access is being denied. Are you running from inside VS or from the exe? If you are running inside VS try starting VS by right click VS shortcut and select Run As Admin. – jdweng Aug 10 '22 at 21:45
  • Yes I run it as a Administrator. So if it is related with access then how I can get response for action which defined inside MapGet().? For action defined insdie MapGet it returns 200 I mean I can get response for it. But for other actions I can not. – FBY Aug 10 '22 at 21:54
  • I can't tell what code is at client and what code is at server. A controller can be either at client or server (or both). Normally you have 5 steps 1) Client sends a Request with PUT. 2) Server receives Receives Request with GET 3) Server processes request 4) Sever sends Response with PUT 5) Client Receives Response with GET. Put/Get are the body data of the Request/Response. The ActionResult is the body (serialized/deserialized data) that maps to a class object. – jdweng Aug 11 '22 at 01:18

1 Answers1

0

Add code in API project in ConfigureWebHost(IWebHostBuilder builder)

builder.UseEnvironment("Test");
builder.ConfigureAppConfiguration((ctx, b) =>
{
    ctx.HostingEnvironment.ApplicationName = typeof(Program).Assembly.GetName().Name;
});
builder.ConfigureServices(services =>
{
    services.AddMvc()
        .AddApplicationPart(typeof(TestStartup).Assembly); //TestStartup is Test project's startup!!
}

And works now thanks!

derloopkat
  • 6,232
  • 16
  • 38
  • 45
FBY
  • 39
  • 5