Automapper fails to initialize in asp.net core Integration Testing project

0

I am getting null reference exception while doing integration testing in aspnetcore project. The project is aspnetcore webapi project that uses full .net framework. The automapper initialization works for the actual webapi project but it fails for integration testing class library project during the dependency injection process.

Exception:

services.AddAutoMapper()

Exception 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

Integration Test Project (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 Project (packages):

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

Integration Test Class:

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

    }
}
c#
asp.net-core
asp.net-core-mvc
automapper
asp.net-core-webapi
asked on Stack Overflow Jul 30, 2017 by bigyanshr • edited Jul 30, 2017 by bigyanshr

1 Answer

1

I had a similar problem, it was solved by specifying the assembly

var assembly = typeof(Program).GetTypeInfo().Assembly;
services.AddAutoMapper(assembly);

which I got from, Integration Testing with AutoMapper fails to initialise configuration

answered on Stack Overflow Nov 12, 2017 by HExit • edited Nov 12, 2017 by Jan Muncinsky

User contributions licensed under CC BY-SA 3.0