TypeLoadException when trying to mock IObjectSet with Moq

4.6k views Asked by At

I have the following setup code:

MockOf<IObjectSet<Dummy>>().Setup(c => c.AddObject(dummy)).Verifiable();
MockOf<IObjectContextWrapper>().Setup(c => c.GetObjectSet<Dummy>()).Returns(MockOf<IObjectSet<Dummy>>().Object);

where Dummy is an empty class definition, and dummy is a Dummy. MockOf<T>() is a mock managing feature on a base class, which basically makes sure that each time it's called on a type, it returns the same mock instance.

The test containing this setup code fails with a TypeLoadException and the following message:

System.TypeLoadException : Type 'IObjectSet`1Proxy389e220f10aa4d9281d0b9e136edc1d4' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=a621a9e7e5c32e69' is attempting to implement an inaccessible interface.

at System.Reflection.Emit.TypeBuilder.TermCreateClass(RuntimeModule module, Int32 tk, ObjectHandleOnStack type)
at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
at System.Reflection.Emit.TypeBuilder.CreateType()
at Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType()
at Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateCode(Type proxyTargetType, Type[] interfaces, ProxyGenerationOptions options)
at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors)
at Moq.Mock1.<InitializeInstance>b__0()
at Moq.Mock
1.InitializeInstance()
at Moq.Mock`1.get_Object()
at OddEnds.Tests.Data.EntityFramework.RepositoryTest.Delete_DeletesObjectFromObjectSet() in RepositoryTest.cs: line 43

I have imported System.Data.Objects and referenced both System.Data.Entity.dll and Microsoft.Data.Entity.CTP.dll in both the test project and the project where the class being tested resides. The build succeeds with no errors, warnings or messages (except a few related to Code Contracts...)

How do I fix this?

3

There are 3 answers

3
Brian Dishaw On BEST ANSWER

Are any of the interfaces or class you are using in your tests internal? Are you using something like [assembly: InternalsVisibleTo("YourTestAssembly")] in order to get things to compile?

If so, you'll also need to add one for DynamicProxyGenAssembly2 in order for Moq to dynamically generate the proxy for the classes.

//goes in the AssemblyInfo.cs where the internal interfaces / classes are defined
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]  

Here is a relevent post about the topic

http://sonofpirate.blogspot.com/2009/09/my-first-foray-into-unit-testing-with.html

I hope this helps

1
The Senator On

I found that in my case I had created a Dummy class instance to be used in my unit test which happened to be private (as I didn't really want to share the test object outside).

My code was along these lines:

var mockMonitor = new Mock<ICacheMonitor<int, PrivateObject>>();

where the PrivateObject was a private class definition within my TestClass. The fix in my case is therefore to ensure that any of the types in your Mock constructor are public.

public class PrivateObject () {}

(Obviously I wouldn't call my public object a PrivateObject either...)

0
Reginald Blue On

I tripped across another case which I couldn't figure out at first. I was working on a proxy for an interface created inside of my unit test...

public IDoWork
{
    void DoWork();
}

It took me forever to figure out that the problem was not with that interface, but was, rather, that the unit test itself was not public:

class TestSomething // missing public keyword
{

// .. some test which tries to create a mock of the interface


    public IDoWork
    {
        void DoWork();
    }

}

So, while IDoWork is says it's public, it really is not since it's enclosed in a private class.

Hope this helps someone.