devlooped / moq

The most popular and friendly mocking framework for .NET
Other
5.8k stars 798 forks source link

System.NullReferenceException : Object reference not set to an instance of an object. #965

Closed rajmondburgaj closed 4 years ago

rajmondburgaj commented 4 years ago

hi,

I have an issue with Moq & NUnit.

below is the issue:

System.NullReferenceException : Object reference not set to an instance of an object.
   at Castle.DynamicProxy.AbstractInvocation.ThrowOnNoTarget()
   at Castle.DynamicProxy.Internal.CompositionInvocation.EnsureValidTarget()
   at Castle.Proxies.Invocations.IInterceptor_get_Name.InvokeMethodOnTarget()
   at Castle.Proxies.IInterceptorProxy.get_Name()
   at Bwin.PosAPI.Modules.UnitTests.Authentication.Interceptors.GenericInterceptorFixture.<>c.<MapLoginSubStates_CheckSubErrorCodeIsMapped_Success>b__2_3(IInterceptor x) in D:\Projects\Platform PosAPI\Test\Modules\UnitTests\Authentication\Interceptors\GenericInterceptorFixture.cs:line 42
   at System.Linq.Enumerable.WhereArrayIterator`1.MoveNext()
   at Bwin.PosAPI.Modules.UnitTests.Authentication.Interceptors.GenericInterceptorFixture.MapLoginSubStates_CheckSubErrorCodeIsMapped_Success() in D:\Projects\Platform PosAPI\Test\Modules\UnitTests\Authentication\Interceptors\GenericInterceptorFixture.cs:line 42

I have an interface defined like this:

public interface IInterceptor
{
        string Name { get; }
}

I want to get all implementations of this and test that none of them contains an empty or null name and some other stuff.

In my setup I have:

            var serviceCollection = new ServiceCollection();
            serviceCollection.TryAddSingleton(p => _staticDataServiceMock.Object);
            serviceCollection.TryAddSingleton(p => _cacheFactoryMock.Object);
            serviceCollection.AddAllImplementationsOf<IInterceptor>();
            var sv = serviceCollection.BuildServiceProvider();
            var interceptors = sv.GetServices<IInterceptor>();

AddAllImplementations method is just a simple one:

        public static IServiceCollection AddAllImplementationsOf<TInterface>(
            this IServiceCollection serviceCollection, ServiceLifetime lifetime = ServiceLifetime.Singleton)
            where TInterface : class
        {
            var types = GetAllImplementations<TInterface>();

            foreach (var type in types)
            {
                serviceCollection.Add(new ServiceDescriptor(type, type, lifetime));
                serviceCollection.Add(new ServiceDescriptor(typeof(TInterface), p => p.GetRequiredService(type), lifetime));
            }

            return serviceCollection;
        }

        private static IEnumerable<Type> GetAllImplementations<TInterface>() where TInterface : class
        { 
            return AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(x => x.GetTypes())
                .Where(x => typeof(TInterface).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract)
                .Select(x => x);
        }

basically I am adding some dependencies and at the end i get all interceptors from the ServiceProvider, store them in a variable and do a foreach on all of them like below.

foreach (var interceptor in interceptors.Where(x => !x.Name.Equals("FAKE")))
{
   //Do testing here
}

I tried to remove the Where condition for a moment but still I get


System.NullReferenceException : Object reference not set to an instance of an object.
   at Castle.DynamicProxy.AbstractInvocation.ThrowOnNoTarget()
   at Castle.DynamicProxy.Internal.CompositionInvocation.EnsureValidTarget()
   at Castle.Proxies.Invocations.IInterceptor_get_Name.InvokeMethodOnTarget()
   at Castle.Proxies.IInterceptorProxy.get_Name()
   at Bwin.PosAPI.Modules.UnitTests.Authentication.Interceptors.GenericInterceptorFixture.MapLoginSubStates_CheckSubErrorCodeIsMapped_Success() in D:\Projects\Platform PosAPI\Test\Modules\UnitTests\Authentication\Interceptors\GenericInterceptorFixture.cs:line 45

Any idea why this might happen ? Do u think that my interface name IInterceptor might cause issues with dynamicproxy or something ?

Funny fact: - this method fails only if I run the whole project. If i run only this one it does not fail. Also, I tried in Visual Studio 2017 & 2019 and both behave the same way. The Moq version was 4.12.0 and then i updated to 4.13.1 but still no luck.

stakx commented 4 years ago

This doesn't appear to be a question about Moq. It seems you're using DynamicProxy directly... but it's hard to tell without seeing more code.

Could you please post a minimal, self-contained, runnable repro code example (aka MCVE)?

rajmondburgaj commented 4 years ago

Hi,

Thanks for the reply, tried to replicate to another project but for some reason I was not able too. Will check one more time next week and see if I can find the issue. Will let you know about the result.

Br

stakx commented 4 years ago

@rajmondburgaj - It's been a while, no repro so far. Should we close this?