集成测试IocManager为Null

问题描述 投票:0回答:1

我设立使用ABP 3.9.0我的Web UI的集成测试。

我已按照https://github.com/aspnetboilerplate/aspnet-core-template/tree/master/test/AbpCompanyName.AbpProjectName.Web.Tests模型

一切编译和执行,但我会在我的测试基类下面的一个空引用异常:

    protected void UsingDbContext(Action<CentralPortalDbContext> action)
    {
        using (var context = IocManager.Resolve<CentralPortalDbContext>())
        {
            action(context);
            context.SaveChanges();
        }
    }

检查调试过程中的功能,它表明IocManager为空。

我已经试过各种排列在所有没有运气的类。

Startup.cs:

using System;
using Abp.AspNetCore;
using Abp.AspNetCore.TestBase;
using Abp.Dependency;
using *****.CentralPortal.EntityFrameworkCore;
using *****.CentralPortal.Web.Controllers;
using Castle.MicroKernel.Registration;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
using System.Collections.Generic;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.AspNetCore.Authentication.Cookies;
using Abp.Reflection.Extensions;

namespace *****.CentralPortal.Web.Tests
{
    public class Startup
    {
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddEntityFrameworkInMemoryDatabase();

            services.AddMvc()
                .PartManager.ApplicationParts.Add(new AssemblyPart(typeof(Web.Startup.CentralPortalWebModule).GetAssembly()));

            JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
            services.AddAuthentication(options =>
            {
                options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
            })

            .AddCookie("Cookies")
            .AddOpenIdConnect(options => SetOpenIdConnectOptions(options));

            services = SetAuthorizations(services);
            //Configure Abp and Dependency Injection
            return services.AddAbp<CentralPortalWebTestModule>(options =>
            {
                options.SetupTest();
            });
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            UseInMemoryDb(app.ApplicationServices);

            app.UseAbp(); //Initializes ABP framework.

            app.UseExceptionHandler("/Error");

            app.UseStaticFiles();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}"
                    );
            });
            app.UseAuthentication();
        }

        private void UseInMemoryDb(IServiceProvider serviceProvider)
        {
            var builder = new DbContextOptionsBuilder<CentralPortalDbContext>();
            builder.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseInternalServiceProvider(serviceProvider);
            var options = builder.Options;

            var iocManager = serviceProvider.GetRequiredService<IIocManager>();

            iocManager.IocContainer
                .Register(
                    Component.For<DbContextOptions<CentralPortalDbContext>>()
                    .Instance(options)
                    .LifestyleSingleton()
                );
        }

        private void SetOpenIdConnectOptions(OpenIdConnectOptions options)
        {

            options.SignInScheme = "Cookies";
            options.Authority = "http://localhost:50052";


            options.RequireHttpsMetadata = false;


            options.ClientId = "centralportal";
            options.ClientSecret = "*************";
            options.ResponseType = OpenIdConnectResponseType.CodeIdToken;
            options.MetadataAddress = $"http://localhost:50052/.well-known/openid-configuration";
            options.SaveTokens = true;
            options.GetClaimsFromUserInfoEndpoint = true;
            options.Scope.Add("openid");
            options.Scope.Add("profile");
            options.Scope.Add("auditingApi");
            options.Scope.Add("ordersApi");
            options.Scope.Add("identityApi");
            options.Scope.Add("offline_access");
            options.Scope.Add("role");

        }

        //Helper method to add all authorization policies
        //Keeps the ConfigureServices method cleaner.
        private IServiceCollection SetAuthorizations(IServiceCollection services)
        {
            services.AddAuthorization(options =>
                options
                .AddPolicy("TestResults", builder =>
                {
                    builder.RequireClaim("role", new List<string> { "TestResults" });
                })
            );
            services.AddAuthorization(options =>
                options
                .AddPolicy("Orders", builder =>
                {
                    builder.RequireRole(new[] { "Orders" });
                })
            );
            services.AddAuthorization(options =>
                options
                .AddPolicy("HomePage", builder =>
                {
                    builder.RequireRole(new[] { "HomePage" });
                })
            );
            services.AddAuthorization(options =>
                options
                .AddPolicy("Dashboard", builder =>
                {
                    builder.RequireRole(new[] { "Dashboard" });
                })
            );
            services.AddAuthorization(options =>
                options
                .AddPolicy("UserAdmin", builder =>
                {
                    builder.RequireRole(new[] { "UserAdmin" });
                })
            );
            services.AddAuthorization(options =>
                options
                .AddPolicy("CustomerAdmin", builder =>
                {
                    builder.RequireRole(new[] { "CustomerAdmin" });
                })
            );

            return services;
        }
    }
}

WebTestBase:

using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Abp.AspNetCore.TestBase;
using *****.CentralPortal.EntityFrameworkCore;
using *****.CentralPortal.Tests.TestDatas;
using AngleSharp.Dom.Html;
using AngleSharp.Parser.Html;
using Microsoft.AspNetCore.Hosting;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Shouldly;
using Abp.Dependency;

namespace *****.CentralPortal.Web.Tests
{
    public abstract class CentralPortalWebTestBase : AbpAspNetCoreIntegratedTestBase<Startup>
    {
        protected static readonly Lazy<string> ContentRootFolder;
        //IIocManager _IocManager;

        static CentralPortalWebTestBase() 
        {
            ContentRootFolder = new Lazy<string>(WebContentDirectoryFinder.CalculateContentRootFolder, true);
        }

        protected CentralPortalWebTestBase() : base()
        {
            UsingDbContext(context => new TestDataBuilder(context).Build());
        }


        protected override IWebHostBuilder CreateWebHostBuilder()
        {
            var _ContentRootFolder = new Lazy<string>(WebContentDirectoryFinder.CalculateContentRootFolder, true);
            UsingDbContext(context => new TestDataBuilder(context).Build());

            return base
                .CreateWebHostBuilder()
                .UseStartup<Startup>()
                .UseContentRoot(_ContentRootFolder.Value);
        }

        #region Get response

        protected async Task<T> GetResponseAsObjectAsync<T>(string url,
            HttpStatusCode expectedStatusCode = HttpStatusCode.OK)
        {
            var strResponse = await GetResponseAsStringAsync(url, expectedStatusCode);
            return JsonConvert.DeserializeObject<T>(strResponse, new JsonSerializerSettings
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
            });
        }

        protected async Task<string> GetResponseAsStringAsync(string url,
            HttpStatusCode expectedStatusCode = HttpStatusCode.OK)
        {
            var response = await GetResponseAsync(url, expectedStatusCode);
            return await response.Content.ReadAsStringAsync();
        }

        protected async Task<HttpResponseMessage> GetResponseAsync(string url,
            HttpStatusCode expectedStatusCode = HttpStatusCode.OK)
        {
            var response = await Client.GetAsync(url);
            response.StatusCode.ShouldBe(expectedStatusCode);
            return response;
        }

        #endregion

        #region UsingDbContext

        protected void UsingDbContext(Action<CentralPortalDbContext> action)
        {
            using (var context = IocManager.Resolve<CentralPortalDbContext>())
            {
                action(context);
                context.SaveChanges();
            }
        }

        protected T UsingDbContext<T>(Func<CentralPortalDbContext, T> func)
        {
            T result;

            using (var context = IocManager.Resolve<CentralPortalDbContext>())
            {
                result = func(context);
                context.SaveChanges();
            }

            return result;
        }

        protected async Task UsingDbContextAsync(Func<CentralPortalDbContext, Task> action)
        {
            using (var context = IocManager.Resolve<CentralPortalDbContext>())
            {
                await action(context);
                await context.SaveChangesAsync(true);
            }
        }

        protected async Task<T> UsingDbContextAsync<T>(Func<CentralPortalDbContext, Task<T>> func)
        {
            T result;

            using (var context = IocManager.Resolve<CentralPortalDbContext>())
            {
                result = await func(context);
                context.SaveChanges();
            }

            return result;
        }

        #endregion

        #region ParseHtml

        protected IHtmlDocument ParseHtml(string htmlString)
        {
            return new HtmlParser().Parse(htmlString);
        }

        #endregion
    }
}

网络测试模块

using Abp.AspNetCore.TestBase;
using Abp.Modules;
using Abp.Reflection.Extensions;
using Castle.MicroKernel.Registration;
using Castle.Windsor.MsDependencyInjection;
using *****.CentralPortal.EntityFrameworkCore;
using *****.CentralPortal.Web.Startup;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;

namespace *****.CentralPortal.Web.Tests
{

    [DependsOn(
        typeof(CentralPortalWebModule),
        typeof(CentralPortalEntityFrameworkCoreModule),
        typeof(AbpAspNetCoreTestBaseModule)
        )]
    public class CentralPortalWebTestModule : AbpModule
    {
        public override void PreInitialize()
        {
            Configuration.UnitOfWork.IsTransactional = false; //EF Core InMemory DB does not support transactions.
        }

        public override void Initialize()
        {
            IocManager.RegisterAssemblyByConvention(typeof(CentralPortalWebTestModule).GetAssembly());
            SetupInMemoryDb();
        }

        private void SetupInMemoryDb()
        {
            var services = new ServiceCollection()
                .AddEntityFrameworkInMemoryDatabase();

            var serviceProvider = WindsorRegistrationHelper.CreateServiceProvider(
                IocManager.IocContainer,
                services
            );

            var builder = new DbContextOptionsBuilder<CentralPortalDbContext>();
            builder.UseInMemoryDatabase().UseInternalServiceProvider(serviceProvider);

            IocManager.IocContainer.Register(
                Component
                    .For<DbContextOptions<CentralPortalDbContext>>()
                    .Instance(builder.Options)
                    .LifestyleSingleton()
            );
        }

    }
}

网络测试类:

using System.Threading.Tasks;
using *****.CentralPortal.Web.Controllers;
using Shouldly;
using Xunit;

namespace *****.CentralPortal.Web.Tests.Controllers
{
    public class HomeController_Tests: CentralPortalWebTestBase
    {
        [Fact]
        public async Task Index_Test()
        {
            string url = GetUrl<HomeController>(nameof(HomeController.Index));
            //Act
            var response = await GetResponseAsStringAsync(
                url
            );

            //Assert
            response.ShouldNotBeNullOrEmpty();
        }

        [Fact]
        public async void ShouldOnlyShowHomeMenuWhenNotAuthorized()
        {
            var response = await GetResponseAsStringAsync(
                GetUrl<HomeController>(nameof(HomeController.Index))
            );

            //Parse the response for menuitems, count them and assert
            int menuitemcount = 0;

            string statuscode = "";//TODO: Gotta parse the response string to get the code
            Assert.Equal(menuitemcount, 2);
        }
    }
}

我不知道为什么IocManager为null,在这一点上。我猜这是我缺少一个简单的配置项,但我似乎无法找到它,或者从我有什么偏差的任何实例。

任何帮助,将不胜感激。

的要求:全异常。

[1/29/2019 8:51:46 AM Informational] [xUnit.net 00:00:02.72]       System.NullReferenceException : Object reference not set to an instance of an object.
[1/29/2019 8:51:46 AM Informational] [xUnit.net 00:00:02.72]       Stack Trace:
[1/29/2019 8:51:46 AM Informational] [xUnit.net 00:00:02.72]         C:\ProjectCode\*****\*****_CentralPortal\test\*****.CentralPortal.Web.Tests\CentralPortalWebTestBase.cs(78,0): at *****.CentralPortal.Web.Tests.CentralPortalWebTestBase.UsingDbContext(Action`1 action)
[1/29/2019 8:51:46 AM Informational] [xUnit.net 00:00:02.72]         C:\ProjectCode\*****\*****_CentralPortal\test\*****.CentralPortal.Web.Tests\CentralPortalWebTestBase.cs(37,0): at *****.CentralPortal.Web.Tests.CentralPortalWebTestBase.CreateWebHostBuilder()
[1/29/2019 8:51:46 AM Informational] [xUnit.net 00:00:02.72]         D:\Github\aspnetboilerplate\src\Abp.AspNetCore.TestBase\AbpAspNetCoreIntegratedTestBase.cs(30,0): at Abp.AspNetCore.TestBase.AbpAspNetCoreIntegratedTestBase`1..ctor()
[1/29/2019 8:51:46 AM Informational] [xUnit.net 00:00:02.72]         C:\ProjectCode\*****\*****_CentralPortal\test\*****.CentralPortal.Web.Tests\CentralPortalWebTestBase.cs(28,0): at *****.CentralPortal.Web.Tests.CentralPortalWebTestBase..ctor()
[1/29/2019 8:51:46 AM Informational] [xUnit.net 00:00:02.72]            at *****.CentralPortal.Web.Tests.Controllers.HomeController_Tests..ctor()
aspnetboilerplate
1个回答
0
投票

因此,它是网络测试模块在下面。我不知道在那里我得到了来自,我认为这是在我从拉一个例子。注释出SetupInMemoryDb();解决了这个问题。

   public override void Initialize()
   {
       IocManager.RegisterAssemblyByConvention(typeof(CentralPortalWebTestModule).GetAssembly());
       SetupInMemoryDb();
   }

   private void SetupInMemoryDb()
   {
       var services = new ServiceCollection()
           .AddEntityFrameworkInMemoryDatabase();

       var serviceProvider = WindsorRegistrationHelper.CreateServiceProvider(
           IocManager.IocContainer,
           services
       );

       var builder = new DbContextOptionsBuilder<CentralPortalDbContext>();
       builder.UseInMemoryDatabase().UseInternalServiceProvider(serviceProvider);

       IocManager.IocContainer.Register(
           Component
               .For<DbContextOptions<CentralPortalDbContext>>()
               .Instance(builder.Options)
               .LifestyleSingleton()
       );
   }
© www.soinside.com 2019 - 2024. All rights reserved.