Unit testing and mocking internal interfaces with RhinoMocks
Im working on a project that i want to cover with unit tests as much as possible.
Problem is that most of the things i need to test are kept internal inside some libraries.
Im not the kind of purist that will avoid unit testing internal classes. If its some very important code i want to test it even if its internal.
Another case when i want to access internal classes is when i want to test some public class that uses some internal classes (via their interfaces).
In this scenario i need to be able to mock those internal interfaces that the public class is using in order to be able to instantiate it and unit test it.
Now some of you experienced TDD people will shout: “Ha haaa that’s easy just use the
[assembly: InternalsVisibleTo(“Some.TestAssembly.Name”)] and your are cool”.
But this is only partial true. Here is why:
Using the InternalsVisibleTo attribute will allow you to access internal members of assembly from the test assembly and use them in unit tests, but if you try to mock them (lets say we use the fantastic RhinoMocks), you will get exception similar to this one:
Castle.DynamicProxy.Generators.GeneratorException: Type is not public, so a proxy cannot be generated.
Type: Roboblob.Implementors.Interfaces.ICookieService
So in this concrete case I have added the InternalsVisibleTo attribute to my main assembly and this allowed the other assembly where my unit tests are to access the internal interface ICookieService but this helped me only half-way. I forgot about RhinoMocks!.
So RhinoMocks cannot create proxy that implements this interface in order to create a mock and throws this exception.
I tried few things to solve this and then i found this link: Rhino Mocks Internal Members.
As most things in life, its very simple once you figure it out: In order to be able to mock internal members of some class you need to allow the RhinoMocks to ‘see’ internals of this class by placing this in your AssemblyInfo.cs:
[assembly: InternalsVisibleTo ("DynamicProxyGenAssembly2")]
Since RhinoMocks must create a proxy class to create a mock and definition for that proxy is in DynamicProxyGenAssembly2 – we need to allow this assembly to access internal members of the assembly holding the class we are testing.
So with this new trick I’m ready to dive into my mocking adventures….
Wish me luck 🙂
Fantastic! Works like a dream. Explanation makes sense to.
Thanks for the write-up.
*too