Wednesday, January 23, 2013

Mocking an internal interface with Moq

The other day I was trying to write some unit tests on a public class with an internal constructor.  In order for the test project to get access to the internal constructor (primarily used for testing) I had to add the assembly: InternalsVisibleTo to the AssemblyInfo.cs file and specify the class library I was testing would expose its internals to the test class library, for example:

[assembly: InternalsVisibleTo("SomeApi.Test")]

This got me close, next issue was the parameter of the internal constructor was an internal interface referencing a dependency of the class under test.  No big deal.  I figured I would use Moq to mock out the dependency and I got the following error when trying to run the test:

Test method SomeNamespace.SomeClass.SomeTestMethod threw exception:
Castle.DynamicProxy.Generators.GeneratorException: Type SomeNamespace.SomeInterface is not public. Can not create proxy for types that are not accessible.

Hmm, it seems like Moq does not have access to the internals.  Adding the following to the class libraries AssemblyInfo.cs file solved the problem

[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

Next time I ran the test Moq was able to access the internal interface and my test passed.

2 comments:

  1. Thanks, this saved me a bit of time. Dealing with accessors and dependency injection is just too much trouble. To expand on what you've done here, though, if you're signing your assembly you will have to specify the public key for your DynamicProxyGenAssembly2. It looks a little like this:

    [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000" +
    "001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852" +
    "f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2" +
    "d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7 ")]

    ReplyDelete
    Replies
    1. Good catch, that is good to know, thanks for the comment.

      Delete