ASP.Net Core React spa integration test

Viewed 704

Asp.Net Core integration testing seems pretty simple but for the life of me I can't test the starter app with my react dev server. It runs fine from a browser so I assume node, npm and react are set up correctly but not under xUnit. It fails with the following exception:

System.AggregateException: One or more errors occurred. ---> System.AggregateException: One or more errors occurred. ---> System.InvalidOperationException: Failed to start 'npm'. To resolve this:.

[1] Ensure that 'npm' is installed and can be found in one of the PATH directories. Current PATH enviroment variable is: {PATH}

Make sure the executable is in one of those directories, or update your PATH.

[2] See the InnerException for further details of the cause. ---> System.ComponentModel.Win32Exception: The directory name is invalid ...

I assume this is because it can't find the content root of my spa so I have tried adding to my web host builder with no luck:

.UseSolutionRelativeContentRoot( "Solution Relative Path to My App" ) );

This is my test class:

public class SampleDataControllerTest
{

    private readonly TestServer server;
    private readonly HttpClient client;

    public SampleDataControllerTest()
    {
        server = new TestServer( WebHost.CreateDefaultBuilder()
            .UseStartup<Startup>()
            .UseSolutionRelativeContentRoot( "Solution Relative Path to My App" ) );
            .UseEnvironment( "Development" );
        client = server.CreateClient();
    }

    [Fact]
    public async Task RootTest()
    {
        HttpResponseMessage page = await client.GetAsync( "/" );
        Assert.NotNull( page );
        Assert.Equal( HttpStatusCode.OK, page.StatusCode );
    }

What am I missing?

1 Answers

The trick for me was setting the development environment variable to point to the directory where the packages.json file resides.

Below is an excerpt of the constructor of my xUnit integration test class.

Note that it first determines the solution directory (using GetExecutingAssembly().Location), and then points to the web source project folder. (In our environment, Client.React is a directory under the solution directory that contains the packages.json file).

Then, the directory is set using Directory.SetCurrentDirectory, followed by the test server being set up wit hthe UseWebRoot, again pointing to the directory where the packages.json file resides.

Startup is the ASP.NET web startup class.

    /// <summary>
    /// Constructor
    /// </summary>
    public IntegrationTest() : base()
    {
        var testAssemblyPath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
        // Remove the "\\bin\\Debug\\netcoreapp2.1"
        var solutionPath = Directory.GetParent(testAssemblyPath.Substring(0, testAssemblyPath.LastIndexOf(@"\bin\", StringComparison.Ordinal))).FullName;
        var clientReactPath = Path.Join(solutionPath, "Client.React");

        // Important to ensure that npm loads and is pointing to correct directory
        Directory.SetCurrentDirectory(clientReactPath);

        var server = new TestServer(new WebHostBuilder()
            .UseEnvironment("Development")
            .UseWebRoot(clientReactPath)
            .UseStartup<Startup>());

        _client = server.CreateClient();

    }
Related