Search code examples
c#asp.net-mvcasp.net-coreintegration-testingurl-routing

Get route to an action from outside the method


Similar to Get the full route to current action, but I want to get the route from outside of the controller method.

  [ApiController]
  public class TestController : ControllerBase {

    public IActionResult OkTest() {
      return Ok(true);
    }
  }

Then a test class:

public class TestControllerTests {

    private readonly HttpClient _client;

    public TestControllerTests() {
      _client = TestSetup.GetTestClient();
    }

    [Test]
    public async Task OkTest() {
      var path = GetPathHere(); // should return "/api/test/oktest". But what is the call?
      var response = await _client.GetAsync(path);
      response.EnsureSuccessStatusCode();
    }
}

Solution

  • This approach seems to provide desired result. But this basically instantiates the whole application in order to get to the configured services:

        private string GetPathHere(string actionName)
        {
            var host = Program.CreateWebHostBuilder(new string[] { }).Build();
            host.Start();
            IActionDescriptorCollectionProvider provider = (host.Services as ServiceProvider).GetService<IActionDescriptorCollectionProvider>();
            return provider.ActionDescriptors.Items.First(i => (i as ControllerActionDescriptor)?.ActionName == actionName).AttributeRouteInfo.Template;
        }
    
        [TestMethod]
        public void OkTestShouldBeFine()
        {
            var path = GetPathHere(nameof(ValuesController.OkTest)); // "api/Values" in my case
        }
    

    However I suspect more complex cases will require a bit more massaging.