Base solution for your next web application
Ends in:
01 DAYS
01 HRS
01 MIN
01 SEC
Open Closed

ProfileAppService_Tests not working Dependency injection in tests #7321


User avatar
0
joe704la created

I am having issues with dependency injection in many of my tests. I basically can't get any of the tests in the ProfileAppService_Tests to work. I get the below.

Castle.MicroKernel.ComponentActivator.ComponentActivatorException : ComponentActivator: could not proxy Authorization.Users.Profile.ProfileAppService ---- System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation. -------- System.ArgumentNullException : Value cannot be null.

One thing I noticed was that all the tests that is having issues with certain services are all ones I added IHostingEnvironment and IConfigurationRoot to resolve.

I tried doing something like this in my TestBaseModule but didn't work. var fakeHostingEnvironment = Substitute.For<IHostingEnvironment>(); IocManager.IocContainer.Register(Component.For<IHostingEnvironment>().Instance(fakeHostingEnvironment).IsDefault());

IocManager.IocContainer.Register(Component.For<IConfigurationRoot>().Instance(FakeAppConfiguration.GetAppConfiguration()).IsDefault());

I am pretty new to wiring tests so any help would be a lot of help. Thank you


8 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team

    Can you simply reproduce your dependency injection problem using Zero's Demo project and share it with me? I can download and help you view it.

    Email: [email protected]

  • User Avatar
    0
    joe704la created

    No I can't replicate it. I am pretty sure it is because in the services that don't work I am using

    private readonly IConfigurationRoot _appConfiguration; and private readonly IHostingEnvironment _env;

    so that I can use the appConfiguration to get some configuration settings in the appsettings.json. This works perfectly fine, except when I try to run the tests. Is there anway that you may know of I can register those two interfaces in the testing world?

    Like I said I tried doing the following but didn't work. var fakeHostingEnvironment = Substitute.For<IHostingEnvironment>(); IocManager.IocContainer.Register(Component.For<IHostingEnvironment>().Instance(fakeHostingEnvironment).IsDefault());

    IocManager.IocContainer.Register(Component.For<IConfigurationRoot>().Instance(FakeAppConfiguration.GetAppConfiguration()).IsDefault());

  • User Avatar
    0
    maliming created
    Support Team

    I use LocalIocManager in unit tests.

  • User Avatar
    0
    joe704la created

    That didn't work for me but then I saw you had a difference in your SessionAppService.

    I was doing the injection like this _appConfiguration = env.GetAppConfiguration();

    Not this _appConfiguration = appConfiguration; If I do it the same way you had it as you can see in my screenshot below. Then it works just fine. Not sure when I should be using the env.GetAppConfiguration(); way over appConfiguration way though. Castle.MicroKernel.ComponentActivator.ComponentActivatorException : ComponentActivator: could not proxy PHS.Sessions.SessionAppService ---- System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation. -------- System.ArgumentException : The path must be absolute. Parameter name: root

  • User Avatar
    0
    joe704la created

    It looks like I have to use env.GetAppConfiguration because if I don't I get the following error when I run the actual app Sessions.SessionAppService' is waiting for the following dependencies:

    • Service 'Microsoft.Extensions.Configuration.IConfigurationRoot' which was not registered.
  • User Avatar
    0
    joe704la created

    Some more info. I tried not using env.GetAppConfiguration and using appConfiguration but that won't find the config file and grab the info from the config file I need.

    So I tried this in the test.

    public SessionAppService_Tests()
            {
                var fakeHostingEnvironment = Substitute.For<IHostingEnvironment>();
                LocalIocManager.IocContainer.Register(Component.For<IHostingEnvironment>().Instance(fakeHostingEnvironment).IsDefault());
    
                LocalIocManager.IocContainer.Register(Component.For<IConfigurationRoot>().Instance(fakeHostingEnvironment.GetAppConfiguration()).IsDefault());
    
    
                _sessionAppService = Resolve<ISessionAppService>();
            }
    
        but got the following error. System.ArgumentException : The path must be absolute.
        
        
    

    System.ArgumentException : The path must be absolute. Parameter name: root at Microsoft.Extensions.FileProviders.PhysicalFileProvider..ctor(String root, ExclusionFilters filters) at Microsoft.Extensions.Configuration.FileConfigurationExtensions.SetBasePath(IConfigurationBuilder builder, String basePath) at PHS.Configuration.AppConfigurations.BuildConfiguration(String path, String environmentName, Boolean addUserSecrets) in \src\PHS.Core\Configuration\AppConfigurations.cs:line 28 at PHS.Configuration.AppConfigurations.<>c__DisplayClass2_0.<Get>b__0(String _) in \src\PHS.Core\Configuration\AppConfigurations.cs:line 22 at System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func2 valueFactory) at PHS.Configuration.AppConfigurations.Get(String path, String environmentName, Boolean addUserSecrets) in \src\PHS.Core\Configuration\AppConfigurations.cs:line 20 at PHS.Configuration.HostingEnvironmentExtensions.GetAppConfiguration(IHostingEnvironment env) in \src\PHS.Core\Configuration\HostingEnvironmentExtensions.cs:line 10 at PHS.Tests.Sessions.SessionAppService_Tests..ctor() in I\test\PHS.Tests\Sessions\SessionAppService_Tests.cs:line 24

    Any suggestions?

  • User Avatar
    0
    maliming created
    Support Team

    You need to simulate interface methods or properties.

    var fakeHostingEnvironment = Substitute.For<IHostingEnvironment>();
    fakeHostingEnvironment.ContentRootPath = Directory.GetCurrentDirectory(); // Or other path
    fakeHostingEnvironment.EnvironmentName = "Development";
    LocalIocManager.IocContainer.Register(Component.For<IHostingEnvironment>().Instance(fakeHostingEnvironment).IsDefault());
    
    

    But if your method needs to read the settings, you may need to use the appsettings.json file in the unit test.

    Reference: https://weblog.west-wind.com/posts/2018/Feb/18/Accessing-Configuration-in-NET-Core-Test-Projects

  • User Avatar
    0
    joe704la created

    Thank you for all the help