ssannandeji / Zenject-2019

Dependency Injection Framework for Unity3D

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Automocking with Moq internal constructor not visible with Reflection

halzate93 opened this issue · comments

Hi,

I'm trying to setup Moq with Unity following the process described at: https://github.com/modesttree/Zenject/blob/master/Documentation/AutoMocking.md

However when I try to call any function inside Moq with the installers I'm getting the same error:

Test1 (0.284s)
---
System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation.
  ----> System.MethodAccessException : Method `Moq.Proxy.InterfaceProxy..ctor()' is inaccessible from method `Castle.Proxies.IFooProxy..ctor(Castle.DynamicProxy.IInterceptor[],object)'
---
at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00014] in <fb001e01371b4adca20013e0ac763896>:0 
  at System.Reflection.MonoCMethod.DoInvoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0007a] in <fb001e01371b4adca20013e0ac763896>:0 
  at System.Reflection.MonoCMethod.Invoke (System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <fb001e01371b4adca20013e0ac763896>:0 
  at System.RuntimeType.CreateInstanceImpl (System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Object[] args, System.Globalization.CultureInfo culture, System.Object[] activationAttributes, System.Threading.StackCrawlMark& stackMark) [0x00213] in <fb001e01371b4adca20013e0ac763896>:0 
  at System.Activator.CreateInstance (System.Type type, System.Reflection.BindingFlags bindingAttr, System.Reflection.Binder binder, System.Object[] args, System.Globalization.CultureInfo culture, System.Object[] activationAttributes) [0x000a1] in <fb001e01371b4adca20013e0ac763896>:0 
  at System.Activator.CreateInstance (System.Type type, System.Object[] args) [0x00000] in <fb001e01371b4adca20013e0ac763896>:0 
  at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget (System.Type interfaceToProxy, System.Type[] additionalInterfacesToProxy, Castle.DynamicProxy.ProxyGenerationOptions options, Castle.DynamicProxy.IInterceptor[] interceptors) [0x00072] in <65dbde134d1941e58e09bbc8bf2facf3>:0 
  at Moq.Proxy.CastleProxyFactory.CreateProxy (System.Type mockType, Moq.Proxy.ICallInterceptor interceptor, System.Type[] interfaces, System.Object[] arguments) [0x00026] in <65dbde134d1941e58e09bbc8bf2facf3>:0 
  at Moq.Mock`1[T].<InitializeInstance>b__0 () [0x0008c] in <65dbde134d1941e58e09bbc8bf2facf3>:0 
  at Moq.PexProtector.Invoke (System.Action action) [0x00000] in <65dbde134d1941e58e09bbc8bf2facf3>:0 
  at Moq.Mock`1[T].InitializeInstance () [0x00000] in <65dbde134d1941e58e09bbc8bf2facf3>:0 
  at Moq.Mock`1[T].OnGetObject () [0x00010] in <65dbde134d1941e58e09bbc8bf2facf3>:0 
  at Moq.Mock.GetObject () [0x00000] in <65dbde134d1941e58e09bbc8bf2facf3>:0 
  at Moq.Mock.get_Object () [0x00000] in <65dbde134d1941e58e09bbc8bf2facf3>:0 
  at Moq.Mock`1[T].get_Object () [0x00000] in <65dbde134d1941e58e09bbc8bf2facf3>:0 
  at Moq.Mocks+<CreateMocks>d__0`1[T].MoveNext () [0x00038] in <65dbde134d1941e58e09bbc8bf2facf3>:0 
  at System.Linq.Enumerable.TryGetFirst[TSource] (System.Collections.Generic.IEnumerable`1[T] source, System.Boolean& found) [0x00045] in <351e49e2a5bf4fd6beabb458ce2255f3>:0 
  at System.Linq.Enumerable.First[TSource] (System.Collections.Generic.IEnumerable`1[T] source) [0x00000] in <351e49e2a5bf4fd6beabb458ce2255f3>:0 
  at (wrapper dynamic-method) System.Object.lambda_method(System.Runtime.CompilerServices.Closure)
  at System.Linq.EnumerableExecutor`1[T].Execute () [0x0001b] in <351e49e2a5bf4fd6beabb458ce2255f3>:0 
  at System.Linq.EnumerableQuery`1[T].System.Linq.IQueryProvider.Execute[TElement] (System.Linq.Expressions.Expression expression) [0x00036] in <351e49e2a5bf4fd6beabb458ce2255f3>:0 
  at System.Linq.Queryable.First[TSource] (System.Linq.IQueryable`1[T] source) [0x0002f] in <351e49e2a5bf4fd6beabb458ce2255f3>:0 
  at (wrapper dynamic-method) System.Object.lambda_method(System.Runtime.CompilerServices.Closure)
  at Moq.Linq.MockQueryable`1[T].Execute[TResult] (System.Linq.Expressions.Expression expression) [0x00025] in <65dbde134d1941e58e09bbc8bf2facf3>:0 
  at System.Linq.Queryable.First[TSource] (System.Linq.IQueryable`1[T] source) [0x0002f] in <351e49e2a5bf4fd6beabb458ce2255f3>:0 
  at Moq.Mock.Of[T] () [0x00005] in <65dbde134d1941e58e09bbc8bf2facf3>:0 
  at Zenject.ZenjectMoqExtensions.FromMock[TContract] (Zenject.FromBinderGeneric`1[TContract] binder) [0x00001] in /Users/halzate/Projects/Zenject/Assets/Plugins/Zenject/Source/Editor/AutoMocking/ZenjectMoqExtensions.cs:18 
  at Zenject.Tests.TestAutoMocking.Test1 () [0x00001] in /Users/halzate/Projects/Zenject/Assets/Plugins/Zenject/Source/Editor/AutoMocking/TestAutoMocking.cs:25 
  at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&)
  at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in <fb001e01371b4adca20013e0ac763896>:0 
--MethodAccessException
  at (wrapper managed-to-native) System.Object.__icall_wrapper_mono_throw_method_access(intptr,intptr)
  at Castle.Proxies.IFooProxy..ctor (Castle.DynamicProxy.IInterceptor[] , System.Object ) [0x0000e] in <1394a50849c941b3a7a5e2d8451d5d73>:0 
  at (wrapper managed-to-native) System.Reflection.MonoCMethod.InternalInvoke(System.Reflection.MonoCMethod,object,object[],System.Exception&)
  at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00002] in <fb001e01371b4adca20013e0ac763896>:0

I tried setting up an independent project with only Zenject and it fails the Unit tests inside the Automocking zip.

image

I'm using Unity 2019.4.6f1 and the Zenject 8.0 release unity package from this github. My Scripting backend doesn't work on neither Mono nor IL2CPP and my API compatibility level is .NET Standard 2.0 so I'm using the 3.5 dll.

image

Here is my repro project:
https://drive.google.com/file/d/1U3Cs6jyFrbhbvJoNPuO8YO6g0aTvUYuF/view?usp=sharing

Is there something obvious I'm missing?

Yes, you need to have Moq.dll installed.
It's in the 'Optional Extras', you will need to unzip the Moq library. And drop it somewhere in your Assets folder.
Then you need to reference the dll from your test folder's asmdef file.
Like this: (Note: I don't have Moq here but NSubstitute)
Schermafbeelding 2020-10-28 om 16 33 59

You can read more about installation here

Referencing assemblies differ in every Unity version since 2019.1. So yo probably need to change the internal Zenject tests as well (if you want to run these from this repo)

Hi @Mathijs-Bakker thanks for your response,

The Moq.dll I used is inside the Automocking folder, that's where the zip ships in. I moved it to the location as you describe but I'm still getting the exact same error. Just to clarify have you seen the error I'm getting before? the one about Moq internal constructor not working with Reflection? It seems like the tests are finding Moq just fine, the problem happens at the reflection step.

I figured it out with the steps you suggested, thank you!