Automapper无法在asp.net核心集成测试项目

时间:2017-07-30 09:00:52

标签: c# asp.net-core asp.net-core-mvc automapper asp.net-core-webapi

我在aspnetcore项目中进行集成测试时得到null引用异常。该项目是使用完整.net框架的aspnetcore webapi项目。自动化程序初始化适用于实际的webapi项目,但在依赖项注入过程中无法进行集成测试类库项目。

例外:

services.AddAutoMapper()

异常Stacktrace:

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);
        }

    }
}

1 个答案:

答案 0 :(得分:1)

我遇到了类似的问题,通过指定程序集

解决了这个问题
var assembly = typeof(Program).GetTypeInfo().Assembly;
services.AddAutoMapper(assembly);

我来自Integration Testing with AutoMapper fails to initialise configuration