Mocking Internal Types with Moq
To perform successful unit testing classes should be isolated from their dependencies. When the dependencies are internal and tests are in a separate project, this can be achieved using a combination of Moq and C# friend assemblies.
Mocking Internal Types
Mocking using the Moq framework provides a simple way to create test doubles that can be provided to a class under test using dependency injection. The mock objects can be pre-programmed with responses to specific calls, letting you isolate the class under test and simplify your unit testing.
In most cases you will structure your solution so that the tests are in a separate project to the types being tested. This allows you to ship the completed application without delivering the test code to your end users. The separate test project can reference the application code and access its public types, testing all of the code through public interfaces.
If you are creating a class library and you do not want all of the types within it to be visible to the library's end users, you may decide to make some classes internal. These can still be used as dependencies but are hidden under normal use. Testing these classes and injecting internal dependencies from a separate test project requires an additional step. The test project must be configured to be a friend assembly of the assembly being tested.
As an example, let's say that you have a project that you wish to test, named "ProjectUnderTest", that contains internal classes. Within the same solution you have a project containing tests that you have named, "Tests". Unless configured otherwise, the internal types of ProjectUnderTest are invisible to the Tests project. Using the techniques described in the article, "C# Friend Assemblies", you can make the internal types visible to the test project. However, if you wish to mock those internal types using Moq, you must also make an assembly from the Moq framework a friend assembly of the project being tested. The name of this assembly is "DynamicProxyGenAssembly2".
If you are not using signed assemblies, you would add the following two attributes to your project.
NB: The attributes should be added to the assembly.cs file of the project under test, not of the project containing the tests.
Mocking Internal Types in Signed Assemblies
If the assembly that you are developing is signed, the InternalsVisibleTo attributes must be updated to hold the public key values for the test assembly and the DynamicProxyGenAssembly2 assembly. You can obtain the public key for your test assembly using the sn.exe tool, as described in the C# Friend Assemblies article. The DynamicProxyGenAssembly2 public key is shown in the updated attribute below:
11 December 2011