Michal Ciechan
Michal Ciechan

Reputation: 13898

VS 2017 ASP.NET Core Test Project - Microsoft.AspNetCore.Identity missing

I am trying to write an integration test for an empty .NET Core ASP site using the Microsoft.AspNetCore.TestHost

Microsoft.AspNetCore.Mvc.Razor.Compilation.CompilationFailedException :
One or more compilation failures occurred:
/Views/_ViewImports.cshtml(5,28): 

error CS0234: The type or namespace name 'Identity' 
does not exist in the namespace 'Microsoft.AspNetCore' 
(are you missing an assembly reference?) 4uvgaffv.11j(34,11): 

error CS0246: The type or namespace name 'System' could not be found 
(are you missing a using directive or an assembly reference?)

My Test class is identical to the documentation one and looks as follows:

public class UnitTest1
{
    private readonly TestServer _server;
    private readonly HttpClient _client;
    public UnitTest1()
    {
        // Arrange
        _server = new TestServer(new WebHostBuilder()
            .UseContentRoot(ContentPath)
            .UseStartup<Startup>());

        _client = _server.CreateClient();
    }

    [Fact]
    public async Task ReturnHelloWorld()
    {
        // Act
        var response = await _client.GetAsync("/");

        response.EnsureSuccessStatusCode();

        var body = await response.Content.ReadAsStringAsync();

        // Assert
        Console.WriteLine("Test");
    }

    private static string ContentPath
    {
        get
        {
            var path = PlatformServices.Default.Application.ApplicationBasePath;
            var contentPath = Path.GetFullPath(Path.Combine(path, $@"..\..\..\..\{nameof(DataTests)}"));
            return contentPath;
        }
    }
}

I have tried adding Microsoft.AspNetCore.Identity 1.1.1 NuGet package to the Test project (same one as MVC Project) but it didn't do anything, although I can see it as missing in the Dependencies dropdown:

enter image description here

I have tried reinstalling those packages, dotnet build, dotnet restore, clean rebuild but still no luck.

Any ideas anyone?

FIX

Final fix for this was (thanks to @Jeffrey

WebHostBuilderExtensions.cs

public static class WebHostBuilderExtensions
{
    private static string ContentPath
    {
        get
        {
            var path = PlatformServices.Default.Application.ApplicationBasePath;
            var contentPath = Path.GetFullPath(Path.Combine(path, $@"..\..\..\..\{nameof(DataTests)}"));
            return contentPath;
        }
    }

    public static IWebHostBuilder ConfigureTestContent(this IWebHostBuilder builder)
    {
        return builder.UseContentRoot(ContentPath);
    }

    public static IWebHostBuilder ConfigureTestServices(this IWebHostBuilder builder)
    {
        return builder.ConfigureServices(services =>
        {
            services.AddMvcCore();
            services.Configure((RazorViewEngineOptions options) =>
            {
                var previous = options.CompilationCallback;
                options.CompilationCallback = (context) =>
                {
                    previous?.Invoke(context);

                    var assembly = typeof(Startup).GetTypeInfo().Assembly;
                    var assemblies = assembly.GetReferencedAssemblies()
                                             .Select(x => MetadataReference.CreateFromFile(Assembly.Load(x).Location))
                                             .ToList();
                    assemblies.Add(MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("mscorlib")).Location));
                    assemblies.Add(MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Private.Corelib")).Location));
                    assemblies.Add(MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("Microsoft.ApplicationInsights.AspNetCore")).Location));
                    assemblies.Add(MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("Microsoft.AspNetCore.Html.Abstractions")).Location));
                    assemblies.Add(MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("Microsoft.AspNetCore.Razor")).Location));
                    assemblies.Add(MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("Microsoft.AspNetCore.Razor.Runtime")).Location));
                    assemblies.Add(MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("Microsoft.AspNetCore.Mvc")).Location));
                    assemblies.Add(MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Runtime")).Location));
                    assemblies.Add(MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Dynamic.Runtime")).Location));
                    assemblies.Add(MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Text.Encodings.Web")).Location));

                    context.Compilation = context.Compilation.AddReferences(assemblies);
                };
            });

            services.AddApplicationInsightsTelemetry();
        });
    }
}

Test.cs

public class UnitTest1
{
    private readonly TestServer _server;
    private readonly HttpClient _client;
    private readonly ITestOutputHelper output;

    public UnitTest1(ITestOutputHelper output)
    {
        this.output = output;

        // Arrange
        _server = new TestServer(new WebHostBuilder()
            .ConfigureTestContent()
            .ConfigureLogging(l => l.AddConsole())
            .UseStartup<Startup>()
            .ConfigureTestServices());

        _client = _server.CreateClient();
    }

    [Fact]
    public async Task ReturnHelloWorld()
    {
        // Act
        var response = await _client.GetAsync("/");

        response.EnsureSuccessStatusCode();

        var body = await response.Content.ReadAsStringAsync();

        // Assert
        output.WriteLine(body);
    }
}

Upvotes: 1

Views: 2499

Answers (1)

Jeffrey van der Stad
Jeffrey van der Stad

Reputation: 66

Had the same issue.. After some digging found a working solution..

The roslyn compiler used in Razor doesn't include the referenced assemblies of the main assembly.. So I added these by looking them up

In the test class add the following code.. Works on my machine™

private static string ContentPath
{
    get
    {
        var path = PlatformServices.Default.Application.ApplicationBasePath;
        var contentPath = Path.GetFullPath(Path.Combine(path, $@"..\..\..\..\{nameof(src)}"));
        return contentPath;
    }
}

.

var builder = new WebHostBuilder()
    .UseContentRoot(ContentPath)
    .ConfigureLogging(factory =>
    {
        factory.AddConsole();
    })
    .UseStartup<Startup>()
    .ConfigureServices(services =>
     {
         services.Configure((RazorViewEngineOptions options) =>
         {
             var previous = options.CompilationCallback;
             options.CompilationCallback = (context) =>
             {
                 previous?.Invoke(context);

                 var assembly = typeof(Startup).GetTypeInfo().Assembly;
                 var assemblies = assembly.GetReferencedAssemblies().Select(x => MetadataReference.CreateFromFile(Assembly.Load(x).Location))
                 .ToList();
                 assemblies.Add(MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("mscorlib")).Location));
                 assemblies.Add(MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Private.Corelib")).Location));
                 assemblies.Add(MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("Microsoft.AspNetCore.Razor")).Location));

                 context.Compilation = context.Compilation.AddReferences(assemblies);
             };
         });
     });

    _server = new TestServer(builder);

Same issue on GitHub repo https://github.com/aspnet/Hosting/issues/954

Upvotes: 4

Related Questions