无法在单元测试中解析参数 'Volo.Abp.Identity.IIdentityRoleRepository roleRepository'

Cannot resolve parameter 'Volo.Abp.Identity.IIdentityRoleRepository roleRepository' in unit tests

我正在尝试为我的测试创建一些租户。我使用的是在 ABP 框架网站(.NET Core,Angular,版本 4.4)创建的模板。在我的 TestBaseModule 中,我添加了这个:

private static void SeedTestData(ApplicationInitializationContext context)
{
    AsyncHelper.RunSync(async () =>
    {
        using (var scope = context.ServiceProvider.CreateScope())
        {
            await scope.ServiceProvider
                .GetRequiredService<IDataSeeder>()
                .SeedAsync();

            scope.ServiceProvider                            // This
                .GetRequiredService<TenantTestDataBuilder>() // This
                .Build();                                    // This
        }
    });
}

这里是 TenantTestDataBuilder 代码:

public class TenantTestDataBuilder : ITransientDependency
{
    private readonly IRepository<Tenant, Guid> _tenantRepository;
    private readonly IUnitOfWork _unitOfWork;
    private readonly ITenantManager _tenantManager;

    public TenantTestDataBuilder(
        IRepository<Tenant, Guid> tenantRepository,
        IUnitOfWork unitOfWork,
        ITenantManager tenantManager)
    {
        _tenantRepository = tenantRepository;
        _unitOfWork = unitOfWork;
        _tenantManager = tenantManager;
    }

    public void Build()
    {
        // ...
    }
}

但是它无法从 DI 获取 TenantTestDataBuilder 并抛出此异常:

[xUnit.net 00:00:01.35]       Volo.Abp.AbpInitializationException : An error occurred during the initialize Volo.Abp.Modularity.OnApplicationInitializationModuleLifecycleContributor phase of the module OrderManagement.OrderManagementTestBaseModule, OrderManagement.TestBase, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: An exception was thrown while activating Volo.Abp.Identity.IdentityDataSeedContributor -> Volo.Abp.Identity.IdentityDataSeeder.. See the inner exception for details.
[xUnit.net 00:00:01.35]       ---- Autofac.Core.DependencyResolutionException : An exception was thrown while activating Volo.Abp.Identity.IdentityDataSeedContributor -> Volo.Abp.Identity.IdentityDataSeeder.
[xUnit.net 00:00:01.35]       -------- Autofac.Core.DependencyResolutionException : None of the constructors found with 'Volo.Abp.Autofac.AbpAutofacConstructorFinder' on type 'Volo.Abp.Identity.IdentityDataSeeder' can be invoked with the available services and parameters:
[xUnit.net 00:00:01.35]       Cannot resolve parameter 'Volo.Abp.Identity.IIdentityRoleRepository roleRepository' of constructor 'Void .ctor(Volo.Abp.Guids.IGuidGenerator, Volo.Abp.Identity.IIdentityRoleRepository, Volo.Abp.Identity.IIdentityUserRepository, Microsoft.AspNetCore.Identity.ILookupNormalizer, Volo.Abp.Identity.IdentityUserManager, Volo.Abp.Identity.IdentityRoleManager, Volo.Abp.MultiTenancy.ICurrentTenant, Microsoft.Extensions.Options.IOptions`1[Microsoft.AspNetCore.Identity.IdentityOptions])'.
[xUnit.net 00:00:01.35]       Stack Trace:
[xUnit.net 00:00:01.36]            at Volo.Abp.Modularity.ModuleManager.InitializeModules(ApplicationInitializationContext context)
[xUnit.net 00:00:01.36]            at Volo.Abp.AbpApplicationBase.InitializeModules()
[xUnit.net 00:00:01.36]            at Volo.Abp.AbpApplicationWithExternalServiceProvider.Initialize(IServiceProvider serviceProvider)
[xUnit.net 00:00:01.36]            at Volo.Abp.Testing.AbpIntegratedTest`1..ctor()
[xUnit.net 00:00:01.36]         /home/mahdi/Desktop/d/Repos/ordermanagement/aspnet-core/test/OrderManagement.TestBase/OrderManagementTestBase.cs(25,0): at OrderManagement.OrderManagementTestBase`1..ctor()
[xUnit.net 00:00:01.36]         /home/mahdi/Desktop/d/Repos/ordermanagement/aspnet-core/test/OrderManagement.TestBase/TestData/UnitTestData_Tests.cs(14,0): at OrderManagement.TestData.UnitTestData_Tests..ctor()
[xUnit.net 00:00:01.36]         ----- Inner Stack Trace -----
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
[xUnit.net 00:00:01.36]            at Autofac.Core.Pipeline.ResolvePipeline.Invoke(ResolveRequestContext ctxt)
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.Middleware.RegistrationPipelineInvokeMiddleware.Execute(ResolveRequestContext context, Action`1 next)
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.Middleware.SharingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.Middleware.CircularDependencyDetectorMiddleware.Execute(ResolveRequestContext context, Action`1 next)
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
[xUnit.net 00:00:01.36]            at Autofac.Core.Pipeline.ResolvePipeline.Invoke(ResolveRequestContext ctxt)
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ResolveRequest request)
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.ResolveOperation.ExecuteOperation(ResolveRequest request)
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.ResolveOperation.Execute(ResolveRequest request)
[xUnit.net 00:00:01.36]            at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(ResolveRequest request)
[xUnit.net 00:00:01.36]            at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)
[xUnit.net 00:00:01.36]            at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters)
[xUnit.net 00:00:01.36]            at Autofac.ResolutionExtensions.Resolve(IComponentContext context, Type serviceType, IEnumerable`1 parameters)
[xUnit.net 00:00:01.36]            at Autofac.ResolutionExtensions.Resolve(IComponentContext context, Type serviceType)
[xUnit.net 00:00:01.36]            at Autofac.Extensions.DependencyInjection.AutofacServiceProvider.GetRequiredService(Type serviceType)
[xUnit.net 00:00:01.36]            at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
[xUnit.net 00:00:01.36]            at Volo.Abp.Data.DataSeeder.SeedAsync(DataSeedContext context)
[xUnit.net 00:00:01.36]            at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous(IInvocation invocation, IInvocationProceedInfo proceedInfo)
[xUnit.net 00:00:01.36]            at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapter.ProceedAsync()
[xUnit.net 00:00:01.36]            at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
[xUnit.net 00:00:01.36]            at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
[xUnit.net 00:00:01.36]         /home/mahdi/Desktop/d/Repos/ordermanagement/aspnet-core/test/OrderManagement.TestBase/OrderManagementTestBaseModule.cs(59,0): at OrderManagement.OrderManagementTestBaseModule.<>c__DisplayClass3_0.<<SeedTestData>b__0>d.MoveNext()
[xUnit.net 00:00:01.36]         --- End of stack trace from previous location ---
[xUnit.net 00:00:01.36]            at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException(Task task)
[xUnit.net 00:00:01.36]            at Nito.AsyncEx.AsyncContext.<>c__DisplayClass15_0.<Run>b__0(Task t)
[xUnit.net 00:00:01.36]            at System.Threading.Tasks.ContinuationTaskFromTask.InnerInvoke()
[xUnit.net 00:00:01.36]            at System.Threading.Tasks.Task.<>c.<.cctor>b__277_0(Object obj)
[xUnit.net 00:00:01.36]            at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
[xUnit.net 00:00:01.36]         --- End of stack trace from previous location ---
[xUnit.net 00:00:01.36]            at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
[xUnit.net 00:00:01.36]            at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
[xUnit.net 00:00:01.36]         --- End of stack trace from previous location ---
[xUnit.net 00:00:01.36]            at Nito.AsyncEx.Synchronous.TaskExtensions.WaitAndUnwrapException(Task task)
[xUnit.net 00:00:01.36]            at Nito.AsyncEx.AsyncContext.Run(Func`1 action)
[xUnit.net 00:00:01.36]            at Volo.Abp.Threading.AsyncHelper.RunSync(Func`1 action)
[xUnit.net 00:00:01.36]         /home/mahdi/Desktop/d/Repos/ordermanagement/aspnet-core/test/OrderManagement.TestBase/OrderManagementTestBaseModule.cs(55,0): at OrderManagement.OrderManagementTestBaseModule.SeedTestData(ApplicationInitializationContext context)
[xUnit.net 00:00:01.36]         /home/mahdi/Desktop/d/Repos/ordermanagement/aspnet-core/test/OrderManagement.TestBase/OrderManagementTestBaseModule.cs(50,0): at OrderManagement.OrderManagementTestBaseModule.OnApplicationInitialization(ApplicationInitializationContext context)
[xUnit.net 00:00:01.36]            at Volo.Abp.Modularity.OnApplicationInitializationModuleLifecycleContributor.Initialize(ApplicationInitializationContext context, IAbpModule module)
[xUnit.net 00:00:01.36]            at Volo.Abp.Modularity.ModuleManager.InitializeModules(ApplicationInitializationContext context)
[xUnit.net 00:00:01.36]         ----- Inner Stack Trace -----
[xUnit.net 00:00:01.36]            at Autofac.Core.Activators.Reflection.ReflectionActivator.GetAllBindings(ConstructorBinder[] availableConstructors, IComponentContext context, IEnumerable`1 parameters)
[xUnit.net 00:00:01.36]            at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
[xUnit.net 00:00:01.36]            at Autofac.Core.Activators.Reflection.ReflectionActivator.<ConfigurePipeline>b__11_0(ResolveRequestContext ctxt, Action`1 next)
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.Middleware.DelegateMiddleware.Execute(ResolveRequestContext context, Action`1 next)
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.Middleware.DisposalTrackingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
[xUnit.net 00:00:01.36]            at Autofac.Builder.RegistrationBuilder`3.<>c__DisplayClass41_0.<PropertiesAutowired>b__0(ResolveRequestContext ctxt, Action`1 next)
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.Middleware.DelegateMiddleware.Execute(ResolveRequestContext context, Action`1 next)
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
[xUnit.net 00:00:01.36]            at Autofac.Extras.DynamicProxy.RegistrationExtensions.<>c__DisplayClass8_0`3.<EnableInterfaceInterceptors>b__1(ResolveRequestContext ctxt, Action`1 next)
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.Middleware.DelegateMiddleware.Execute(ResolveRequestContext context, Action`1 next)
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt)
[xUnit.net 00:00:01.36]            at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action`1 next)
[xUnit.net 00:00:01.37]   Finished:    OrderManagement.TestBase
----- Test Execution Summary -----

有什么问题吗?我正在做 ABP Framework 的 AbpTenantManagementTestBaseModule.

这是我在 https://abp.io/get-started

中使用的模板

运行 OS: Ubuntu 20.04

不要更改您的 SeedTestData 方法。因为它负责为您的测试数据播种。您无需添加 TenantTestDataBuilder 即可播种与租户相关的数据。它也对此负责。

private static void SeedTestData(ApplicationInitializationContext context)
        {
            AsyncHelper.RunSync(async () =>
            {
                using (var scope = context.ServiceProvider.CreateScope())
                {
                    await scope.ServiceProvider
                        .GetRequiredService<IDataSeeder>()
                        .SeedAsync();
                }
            });
        }

您只需将数据播种到 YourTestDataSeedContributor class 的 SeedAsyncMethod

public class YourTestDataSeedContributor : IDataSeedContributor, ITransientDependency 
{
   private readonly ITenantRepository _tenantRepository;
   private readonly IUnitOfWork _unitOfWork;
   private readonly ITenantManager _tenantManager;

   public YourTestDataSeedContributor(ITenantRepository tenantRepository, IUnitOfWork unitOfWork, ITenantManager tenantManager)
   {
      _tenantRepository = tenantRepository;
      _unitOfWork = unitOfWork;
       _tenantManager = tenantManager;
   }
   
   public async Task SeedAsync(DataSeedContext context)
   {
      await AddTenantsAsync();
   }

   public async Task AddTenantsAsync()
   {
      var testData = new OrderManagementTestData();
      var tenant = await CreateTenantAsync(testData.DefaultTenantName);
   }

   private async Task<Tenant> CreateTenantAsync(string name)
   {
      var tenant = await _tenantManager.CreateAsync(name);
        
      await _tenantRepository.InsertAsync(tenant);
      await _unitOfWork.SaveChangesAsync();
        
      return tenant;
   }
} 

SeedAsyncMethod 中播种数据后,您可以在测试中使用它。

Cannot resolve parameter 'Volo.Abp.Identity.IIdentityRoleRepository roleRepository' ...
...
.../ordermanagement/aspnet-core/test/OrderManagement.TestBase/TestData/UnitTestData_Tests.cs(14,0): at OrderManagement.TestData.UnitTestData_Tests..ctor()

您不应在 OrderManagement.TestBase 项目中编写测试。

移动OrderManagement.TestBase/TestData/UnitTestData_Tests.cs
OrderManagement.EntityFrameworkCore.Tests/TestData/UnitTestData_Tests.cs

// public class UnitTestData_Tests: OrderManagementTestBase<OrderManagementTestBaseModule>
   public class UnitTestData_Tests: OrderManagementEntityFrameworkCoreTestBase