Ayende @ Wiki

You can also use Rhino Mocks to mock internal classes or methods - for example:

internal class Class1
{
	internal virtual string TestMethod()
	{
		return "TestMethod";
	}

internal virtual string TestProperty { get { return "TestProperty"; } } }


You can mock both the TestMethod and TestProperty inside your unit tests (the example is for .Net 2.0 onwards):

[Test]
public void MockingInternalMethodsAndPropertiesOfInternalClass()
{
	
	Class1 testClass = new Class1();
	string testMethod = testClass.TestMethod();
	string testProperty = testClass.TestProperty;
	MockRepository mockRepository = new MockRepository();

Class1 mockTestClass = mockRepository.CreateMock<Class1>(); Expect.Call(mockTestClass.TestMethod()).Return("MockTestMethod"); Expect.Call(mockTestClass.TestProperty).Return("MockTestProperty");

mockRepository.ReplayAll();

Assert.AreEqual("MockTestMethod", mockTestClass.TestMethod()); Assert.AreEqual("MockTestProperty", mockTestClass.TestProperty);

mockRepository.VerifyAll(); }


When a class is mocked, a new class is generated at run-time which is derived from the mocked class. This generated class resides in a separate "temporary" assembly which is called "DynamicProxyGenAssembly2". So, the InternalsVisibleTo attribute needs to be set on the target assembly to allow access to its internal members from the temporary assembly; otherwise, the mock object can't override the internal member as it doesn't have access to it (which is also why the mocked method must be marked as virtual). Note that this is true even if the unit test and the tested class are in the same assembly.

So, you need to make sure that the target class' assembly makes its internals visible to the proxy assembly as such (in AssemblyInfo.cs for example):

[assembly: InternalsVisibleTo ("DynamicProxyGenAssembly2")]


If you are using strong-named assemblies, this can be achieved as such:

[assembly: InternalsVisibleTo(Rhino.Mocks.RhinoMocks.StrongName)]


The RhinoMocks.StrongName is a convenient way to avoid copying and pasting the full strong name for DynamicProxyGenAssembly2, at the cost of adding a dependency on Rhino.Mocks to your main assembly. If you want to avoid this, you can also use the contents of the RhinoMocks.StrongName string rather than referencing the field:

[assembly: InternalsVisibleTo ("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]


This method is perhaps less convenient insofar as the public key could change from on release to the next. Note that the key I pasted above is correct for RhinoMocks 3.0.1 (and should be valid for the 3.0.x series), but could be different in previous or further releases.

Up: Rhino Mocks Documentation
Next: Rhino Mocks Record-playback Syntax

ScrewTurn Wiki version 2.0 Beta. Some of the icons created by FamFamFam.