Base solution for your next web application
Open Closed

How to use multiple appsettings.json files in Test Module? #4389


User avatar
0
manojreddy created

I have a requirement that I have to read/use two appsettings.json file, but it's not working.

Please find my code below.

using System;
using Abp.AutoMapper;
using Abp.Configuration.Startup;
using Abp.Dependency;
using Abp.Domain.Repositories;
using Abp.Modules;
using Abp.Net.Mail;
using Abp.TestBase;
using Abp.Zero.Configuration;
using Castle.MicroKernel.Registration;
using MyCompany.MyProject.Articles;
using MyCompany.MyProject.Business.DAL;
using MyCompany.MyProject.Business.Dto.Articles;
using MyCompany.MyProject.Business.Dto.Classifications;
using MyCompany.MyProject.Business.Dto.Common;
using MyCompany.MyProject.Business.Dto.Currency;
using MyCompany.MyProject.Business.Dto.Deposit;
using MyCompany.MyProject.Business.Dto.PromoPack;
using MyCompany.MyProject.Business.Dto.Property;
using MyCompany.MyProject.Business.Dto.Suppliers;
using MyCompany.MyProject.Business.Dto.Taxes;
using MyCompany.MyProject.Business.Dto.TenderTypes;
using MyCompany.MyProject.Business.Model.Articles;
using MyCompany.MyProject.Business.Model.Common;
using MyCompany.MyProject.Business.Model.Stores;
using MyCompany.MyProject.Business.Model.Suppliers;
using MyCompany.MyProject.Business.Model.Taxes;
using MyCompany.MyProject.Business.Repositories.Interfaces;
using MyCompany.MyProject.Business.Repositories.Repositories;
using MyCompany.MyProject.Common;
using MyCompany.MyProject.EntityFrameworkCore;
using MyCompany.MyProject.PromoPack;
using MyCompany.MyProject.Security.Recaptcha;
using MyCompany.MyProject.Tests.DependencyInjection;
using MyCompany.MyProject.Tests.Url;
using MyCompany.MyProject.Tests.Web;
using MyCompany.MyProject.Url;
using NSubstitute;
using MyCompany.MyProject.Business.Dto.Stores;
using MyCompany.MyProject.Business.Services.Articles;
using MyCompany.MyProject.Configuration;
using MyCompany.MyProject.Processors.Core;
using Abp.AspNetZeroCore;
using Microsoft.Extensions.Configuration;
using System.IO;

namespace MyCompany.MyProject.Tests
{
    [DependsOn(
        typeof(MyProjectServicesModule),
        typeof(MyProjectEntityFrameworkCoreModule),
        typeof(MyProjectRepositoryModule),
        typeof(AbpTestBaseModule))]
    public class MyProjectTestModule : AbpModule
    {
        public MyProjectTestModule(MyProjectEntityFrameworkCoreModule abpZeroTemplateEntityFrameworkCoreModule)
        {
            abpZeroTemplateEntityFrameworkCoreModule.SkipDbContextRegistration = true;
        }

        public override void PreInitialize()
        {
            var configuration = GetConfiguration();

            Configuration.UnitOfWork.Timeout = TimeSpan.FromMinutes(30);
            Configuration.UnitOfWork.IsTransactional = false;

            //Disable static mapper usage since it breaks unit tests (see https://github.com/aspnetboilerplate/aspnetboilerplate/issues/2052)
            Configuration.Modules.AbpAutoMapper().UseStaticMapper = false;

            //Use database for language management
            Configuration.Modules.Zero().LanguageManagement.EnableDbLocalization();

            RegisterFakeService<AbpZeroDbMigrator>();

            IocManager.Register<IAppUrlService, FakeAppUrlService>();
            IocManager.Register<IWebUrlService, FakeWebUrlService>();
            IocManager.Register<IRecaptchaValidator, FakeRecaptchaValidator>();
            IocManager.Register<IJobLeaseManager, BlobStorageJobLeaseManager>();
            IocManager.Register<IJobQueueManager, JobQueueManager>();

            Configuration.ReplaceService<IAppConfigurationAccessor, TestAppConfigurationAccessor>();
            Configuration.ReplaceService<IEmailSender, NullEmailSender>(DependencyLifeStyle.Transient);

            Configuration.Modules.AspNetZero().LicenseCode = configuration["AbpZeroLicenseCode"];

        }

        public override void Initialize()
        {
            ServiceCollectionRegistrar.Register(IocManager);
        }

        private void RegisterFakeService<TService>()
            where TService : class
        {
            IocManager.IocContainer.Register(
                Component.For<TService>()
                    .UsingFactoryMethod(() => Substitute.For<TService>())
                    .LifestyleSingleton()
            );
        }

        private static IConfigurationRoot GetConfiguration()
        {
            return AppConfigurations.Get(Directory.GetCurrentDirectory(), addUserSecrets: true);
        }
    }
}

I have overwritten the TestAppConfigurationAccessor file like this.

using Abp.Dependency;
using Microsoft.Extensions.Configuration;
using MyCompany.MyProject.Configuration;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace MyCompany.MyProject.Tests
{
    public class TestAppConfigurationAccessor : IAppConfigurationAccessor, ISingletonDependency
    {
        public IConfigurationRoot Configuration { get; }

        public TestAppConfigurationAccessor()
        {
            Configuration = BuildConfig();
        }

        private IConfigurationRoot BuildConfig()
        {
            var currentPath = Directory.GetCurrentDirectory();

            var config = new ConfigurationBuilder()
                .AddJsonFile(Path.Combine(currentPath, "..", "..", "..", "..", "..", "src", "MyCompany.MyProject.Web.Host", $"appsettings.json"), false);

            config.AddJsonFile(Path.Combine(currentPath, $"testingappsettings.json"), false);

            return config.Build();
        }
    }
}

AppConfigurations file:

using System.Collections.Concurrent;
using Abp.Extensions;
using Abp.Reflection.Extensions;
using Microsoft.Extensions.Configuration;

namespace MyCompany.MyProject.Configuration
{
    public static class AppConfigurations
    {
        private static readonly ConcurrentDictionary<string, IConfigurationRoot> ConfigurationCache;

        static AppConfigurations()
        {
            ConfigurationCache = new ConcurrentDictionary<string, IConfigurationRoot>();
        }

        public static IConfigurationRoot Get(string path, string environmentName = null, bool addUserSecrets = false)
        {
            var cacheKey = path + "#" + environmentName + "#" + addUserSecrets;
            return ConfigurationCache.GetOrAdd(
                cacheKey,
                _ => BuildConfiguration(path, environmentName, addUserSecrets)
            );
        }

        private static IConfigurationRoot BuildConfiguration(string path, string environmentName = null, bool addUserSecrets = false)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(path)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

            if (!environmentName.IsNullOrWhiteSpace())
            {
                builder = builder.AddJsonFile($"appsettings.{environmentName}.json", optional: true);
            }

            builder = builder.AddEnvironmentVariables();

            if (addUserSecrets)
            {
                builder.AddUserSecrets(typeof(AppConfigurations).GetAssembly());
            }

            return builder.Build();
        }
    }
}

testingappsettings.json:

{
  "MasterDataFiles": {
    "TestingEntity1": {
      "UseStaging": "true"
    },
    "TestingEntity2": {
      "UseStaging": "false"
    }
  }
}

appsettings.json:

{
"AbpZeroLicenseCode": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}

Please let me know if its possible with only one json.

I tried to copy the contents of one json to another, but my test cases are failing and I'm not able to debug tests.


5 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @ManojReddy,

    Can you send your project to us via email (<a href="mailto:[email protected]">[email protected]</a>)? We can fix this problem for you.

  • User Avatar
    0
    manojreddy created

    Any updates please?

  • User Avatar
    0
    manojreddy created

    Any updates?

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    We have replied your email. It seems like your code is working correctly.

  • User Avatar
    0
    manojreddy created

    Thanks Dear :)