pengweiqhca / Xunit.DependencyInjection

Use Microsoft.Extensions.DependencyInjection to resolve xUnit test cases.
MIT License
370 stars 49 forks source link

Document how to use with WebApplicationFactory #86

Closed goldsam closed 1 year ago

goldsam commented 1 year ago

Please document how to use this library along with WebApplicationFactory

pengweiqhca commented 1 year ago

Sorry, I have rarely used WebApplicationFactory and I need to research to know if and how to integrate.

WeihanLi commented 1 year ago

WebApplicationFactory is based on the test server

I'd like to suggest using the test server directly, hope these two samples would help

goldsam commented 1 year ago

My primary use case for WebApplicationFactory is to bootstrap a test-harness for an application written using top-level statements such as this one taken from the docs.

This approach would adhere to the open-closed principle by allowing dependencies to be overridden without requiring the application's code be modified. The alternative I see is to use a Startup class in the main app, however it seems this is a legacy approach with newer projects moving towards top-level statements.

What are your thoughts and opinions?

WeihanLi commented 1 year ago

I add a MinimalAPI sample here https://github.com/WeihanLi/XunitDependencyInjection.Samples/tree/main/P6_MinimalAPI hope it would help

goldsam commented 1 year ago

@WeihanLi The issue with this approach is that the unit tests and the web application each have their own distinct dependency injection containers. To allow the web application to log to the unit test log output I had to inject the ILoggerProvider from the test environment into the web application as follows:

using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.Extensions.Logging;

namespace MinimalApiTest;

public sealed class TestWebApplicationFactory: WebApplicationFactory<Program>
{
    private readonly ILoggerProvider _loggerProvider;

    public TestWebApplicationFactory(ILoggerProvider loggerProvider)
    {
        _loggerProvider = loggerProvider;
    }

    protected override IWebHostBuilder? CreateWebHostBuilder()
    {
        builder.ConfigureTestServices(services => services.AddSingleton(_loggerProvider));

        return base.CreateWebHostBuilder();
    }
}

This is assuming the use of the latest release (at time of writing) of Xunit.DependencyInjection.Logging.

While this does technically work, it gets to be cumbersome and potentially error-prone when you want to inject additional services shared by both your tests and the web application. I don't see this approach as being viable. I would prefer a solution with just a single DI container.

pengweiqhca commented 1 year ago

If you want to Integration with WebApplicationFactory, you can use XunitWebApplicationFactory. If you just output logs to xunit output, you should use MartinCostello.Logging.XUnit.

pengweiqhca commented 1 year ago

Asp.Net Core MinimalApi