0

我在aspnetcore项目中进行集成测试时收到空引用异常。该项目是使用完整.net框架的aspnetcore webapi项目。自动映射器初始化适用于实际的webapi项目,但在依赖注入过程中集成测试类库项目失败。Automapper无法在asp.net核心集成测试项目中初始化

例外:

services.AddAutoMapper()

异常堆栈跟踪:

System.ArgumentNullException occurred 
    HResult=0x80004003 
    Message=Value cannot be null. 
    Source=Microsoft.Extensions.DependencyModel 
    StackTrace: 
    at Microsoft.Extensions.DependencyModel.DependencyContextLoader.Load(Assembly assembly) 
    at Microsoft.Extensions.DependencyModel.DependencyContext.LoadDefault() 
    at System.Lazy`1.CreateValue() 
    at System.Lazy`1.LazyInitValue() 
    at System.Lazy`1.get_Value() 
    at AutoMapper.ServiceCollectionExtensions.AddAutoMapper(IServiceCollection services) 
    at EI.CatalogBuilder.WebService.Startup.ConfigureServices(IServiceCollection services) in F:\ei_cube_customization\EI.CatalogBuilder\EI.CatalogBuilder.WebService\Startup.cs:line 154 

集成测试项目(packages.config):

<?xml version="1.0" encoding="utf-8"?> 
 
<packages> 
 
    <package id="AutoMapper" version="6.1.1" targetFramework="net46" /> 
 
    <package id="AutoMapper.Extensions.Microsoft.DependencyInjection" version="2.0.1" targetFramework="net46" /> 
 
    <package id="EntityFramework" version="6.1.3" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.Antiforgery" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.Authorization" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.Cryptography.Internal" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.DataProtection" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.DataProtection.Abstractions" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.Diagnostics.Abstractions" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.Hosting" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.Hosting.Abstractions" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.Hosting.Server.Abstractions" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.Html.Abstractions" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.Http" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.Http.Abstractions" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.Http.Extensions" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.Http.Features" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.JsonPatch" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.Mvc.Abstractions" version="1.1.3" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.Mvc.Core" version="1.1.3" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.Mvc.DataAnnotations" version="1.1.3" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.Mvc.Formatters.Json" version="1.1.3" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.Mvc.ViewFeatures" version="1.1.3" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.ResponseCaching.Abstractions" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.Routing" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.Routing.Abstractions" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.TestHost" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.AspNetCore.WebUtilities" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.CSharp" version="4.3.0" targetFramework="net46" /> 
 
    <package id="Microsoft.DotNet.PlatformAbstractions" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.Extensions.Configuration" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.Extensions.Configuration.Abstractions" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.Extensions.Configuration.EnvironmentVariables" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.Extensions.DependencyInjection" version="1.1.1" targetFramework="net46" /> 
 
    <package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="1.1.1" targetFramework="net46" /> 
 
    <package id="Microsoft.Extensions.DependencyModel" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.Extensions.FileProviders.Abstractions" version="1.1.1" targetFramework="net46" /> 
 
    <package id="Microsoft.Extensions.FileProviders.Physical" version="1.1.1" targetFramework="net46" /> 
 
    <package id="Microsoft.Extensions.FileSystemGlobbing" version="1.1.1" targetFramework="net46" /> 
 
    <package id="Microsoft.Extensions.Localization" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.Extensions.Localization.Abstractions" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.Extensions.Logging" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.Extensions.Logging.Abstractions" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.Extensions.ObjectPool" version="1.1.1" targetFramework="net46" /> 
 
    <package id="Microsoft.Extensions.Options" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.Extensions.PlatformAbstractions" version="1.1.0" targetFramework="net46" /> 
 
    <package id="Microsoft.Extensions.Primitives" version="1.1.1" targetFramework="net46" /> 
 
    <package id="Microsoft.Extensions.WebEncoders" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.Net.Http.Headers" version="1.1.2" targetFramework="net46" /> 
 
    <package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="net46" /> 
 
    <package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="net46" /> 
 
    <package id="NETStandard.Library" version="1.6.1" targetFramework="net46" /> 
 
    <package id="Newtonsoft.Json" version="10.0.3" targetFramework="net46" /> 
 
    <package id="NSubstitute" version="2.0.3" targetFramework="net46" /> 
 
    <package id="NUnit" version="3.7.1" targetFramework="net46" /> 
 
    <package id="NUnit3TestAdapter" version="3.8.0" targetFramework="net46" /> 
 
    <package id="System.AppContext" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Buffers" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Collections" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Collections.Immutable" version="1.3.1" targetFramework="net46" /> 
 
    <package id="System.ComponentModel" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Console" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Diagnostics.Contracts" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Diagnostics.DiagnosticSource" version="4.4.0" targetFramework="net46" /> 
 
    <package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Diagnostics.Tracing" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Globalization" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Globalization.Calendars" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.IO" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.IO.Compression" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.IO.Compression.ZipFile" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.IO.FileSystem" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Linq" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Linq.Expressions" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Net.Http" version="4.3.2" targetFramework="net46" /> 
 
    <package id="System.Net.Primitives" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Net.Sockets" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.ObjectModel" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Reflection" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Reflection.Extensions" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Reflection.Metadata" version="1.4.2" targetFramework="net46" /> 
 
    <package id="System.Reflection.Primitives" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Runtime" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Runtime.CompilerServices.Unsafe" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Runtime.Extensions" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Runtime.Handles" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Text.Encoding" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Text.Encodings.Web" version="4.3.1" targetFramework="net46" /> 
 
    <package id="System.Text.RegularExpressions" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Threading" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Threading.Tasks" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Threading.Timer" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net46" /> 
 
    <package id="System.Xml.XDocument" version="4.3.0" targetFramework="net46" /> 
 
</packages>

的Web API项目(包):

enter image description here

Startup.cs:

using Microsoft.AspNetCore.Builder; 
using Microsoft.AspNetCore.Hosting; 
using Microsoft.Extensions.Configuration; 
using Microsoft.Extensions.DependencyInjection; 
using Microsoft.Extensions.Logging; 
using Microsoft.AspNetCore.Mvc; 
using Newtonsoft.Json; 
using Microsoft.AspNetCore.Authentication.Cookies; 
using System.Threading.Tasks; 
using Microsoft.IdentityModel.Tokens; 
using System.Text; 
using Microsoft.AspNetCore.Mvc.Versioning; 
using EI.CatalogBuilder.ActiveDirectory.Identity.Models; 
using Microsoft.AspNetCore.Identity; 
using EI.CatalogBuilder.ActiveDirectory.Identity.Stores; 
using EI.CatalogBuilder.ActiveDirectory.Identity.DataAccess; 
using EI.CatalogBuilder.WebService.Utils.SecurityPolicies; 
using Microsoft.AspNetCore.Authorization; 
using EI.CatalogBuilder.WebService.Utils.SecurityPolicies.Handlers; 
using EI.CatalogBuilder.WebService.Utils; 
using Microsoft.AspNetCore.Mvc.Cors.Internal; 
using NLog.Extensions.Logging; 
using NLog.Web; 
using Microsoft.AspNetCore.Http; 
using EI.CatalogBuilder.WebService.Repositories; 
using EI.CatalogBuilder.Infrastructure.Data; 
using AutoMapper; 

namespace EI.CatalogBuilder.WebService 
{ 
    public class Startup 
    { 
     private readonly IHostingEnvironment _env; 
     private readonly ConfigReader _configReader; 

     private IConfigurationRoot _config { get; } 


     public Startup(IHostingEnvironment env) 
     { 
      var builder = new ConfigurationBuilder() 
       .SetBasePath(env.ContentRootPath) 
       .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) 
       .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) 
       .AddEnvironmentVariables(); 
      _config = builder.Build(); 

      _configReader = new ConfigReader(_config); 
      _env = env; 

      _env.ConfigureNLog("nlog.config"); 
     } 

     // This method gets called by the runtime. Use this method to add services to the container. 
     public void ConfigureServices(IServiceCollection services) 
     { 
      services.AddSingleton(_config); 
      services.AddSingleton(_configReader); 

      services.AddTransient<ModuleRepository, ModuleRepository>(); 
      services.AddTransient<ClientRepository, ClientRepository>(); 
      services.AddTransient<CatalogBuilderUnitOfWork, CatalogBuilderUnitOfWork>(); 

      services.AddSingleton<IAuthorizationHandler, DevelopersRequirementHandler>(); 
      services.AddSingleton<IAuthorizationHandler, PublishersRequirementHandler>(); 
      services.AddSingleton<IAuthorizationHandler, ViewersRequirementHandler>(); 

      services.AddTransient<IUserContext<User>, ActiveDirectoryUserContext>(); 
      services.AddTransient<IRoleContext<Role>, ActiveDirectoryRoleContext>(); 

      // Add framework services. 

      // Add identity types 
      services.AddIdentity<User, Role>() 
       .AddDefaultTokenProviders(); 

      // Identity Services 
      services.AddTransient<IUserStore<User>, UserStore<User>>(); 
      services.AddTransient<IRoleStore<Role>, RoleStore<Role>>(); 

      services.Configure<IdentityOptions>(options => 
      { 
       options.Cookies.ApplicationCookie.Events = 
        new CookieAuthenticationEvents 
        { 
         OnRedirectToLogin = (ctx) => 
         { 
          if (ctx.Response.StatusCode == 200) 
          { 
           ctx.Response.StatusCode = 401; 
          } 

          return Task.CompletedTask; 
         }, 

         OnRedirectToAccessDenied = (ctx) => 
         { 
          if (ctx.Response.StatusCode == 200) 
          { 
           ctx.Response.StatusCode = 403; 
          } 

          return Task.CompletedTask; 
         } 
        }; 
      }); 

      services.AddApiVersioning(configuration => { 
       var majorVersion = _configReader.GetApiMajorVersion(); 
       var minorVersion = _configReader.GetApiMinorVersion(); 

       configuration.DefaultApiVersion = new ApiVersion(majorVersion, minorVersion); 
       configuration.AssumeDefaultVersionWhenUnspecified = true; 
       configuration.ReportApiVersions = true; 

       configuration.ApiVersionReader = new HeaderApiVersionReader("ver"); 
      }); 

      services.AddCors(configuration => 
      { 
       configuration.AddPolicy("Default", builder => 
       { 
        builder.AllowAnyHeader() 
         .AllowAnyMethod() 
         .WithOrigins(_configReader.GetCorsDefaultOrigin()); 
       }); 
      }); 

      services.AddAuthorization(configuration => 
      { 
       configuration.AddPolicy("Developers", policy => policy.Requirements.Add(new DevelopersRequirement())); 
       configuration.AddPolicy("Publishers", policy => policy.Requirements.Add(new PublishersRequirement())); 
       configuration.AddPolicy("Viewers", policy => policy.Requirements.Add(new ViewersRequirement())); 
      }); 

      services.AddMvc(options => 
      { 
       // We are supporting SSL for all environments but the development environment 
       if (!_env.IsDevelopment()) 
       { 
        options.Filters.Add(new RequireHttpsAttribute()); 
       } 
      }) 
      .AddJsonOptions(options => 
      { 
       options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; 
      }); 

      services.Configure<MvcOptions>(options => 
      { 
       options.Filters.Add(new CorsAuthorizationFilterFactory("Default")); 
      }); 

      services.AddAutoMapper(); 

      services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); 

     } 

     // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
     public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
     { 
      loggerFactory.AddNLog(); 
      app.AddNLogWeb(); 

      app.UseIdentity(); 

      app.UseJwtBearerAuthentication(new JwtBearerOptions 
      { 
       AutomaticAuthenticate = true, 
       AutomaticChallenge = true, 
       TokenValidationParameters = new TokenValidationParameters 
       { 
        ValidIssuer = _configReader.GetJwtTokenIssuer(), 
        ValidAudience = _configReader.GetJwtTokenAudience(), 
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configReader.GetJwtTokenKey())), 
        ValidateLifetime = true 
       } 
      }); 

      app.UseMvc(); 
     } 
    } 
} 

集成测试类:

using Microsoft.AspNetCore.Hosting; 
using Microsoft.AspNetCore.TestHost; 
using NUnit.Framework; 
using System.Net.Http; 
using System.Threading.Tasks; 

namespace EI.CatalogBuilder.WebService.Tests.IntegrationTests 
{ 
    public class EntityControllerTests 
    { 
     private readonly TestServer _server; 
     private readonly HttpClient _client; 

     public EntityControllerTests() 
     { 
      _server = new TestServer(new WebHostBuilder() 

       .UseStartup<Startup>()); 
      _client = _server.CreateClient(); 
     } 

     [Test] 
     public async Task GetRetunsEmptyListInitially() 
     { 
      var request = "/api/Modules"; 

      var response = await _client.GetAsync(request); 
      response.EnsureSuccessStatusCode(); 

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

      // Assert 
      Assert.AreEqual("[]", responseString); 
     } 

    } 
} 

回答

相关问题