Ayende @ Rahien

My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:


+972 52-548-6969

, @ Q c

Posts: 6,026 | Comments: 44,842

filter by tags archive

Don't like visibility levels, change that

time to read 1 min | 187 words

This came up with respect to MS MVC. The MS MVC team has decided to make some methods protected, and that makes testing using Rhino Mocks a bit of a pain.

Let us assume that I want test that the call to ProductController.Index() will render the "index.aspx" view. I can do something like:

public void ShouldAskToRenderTheIndexAspxView()
	MockRepository mocks = new MockRepository();
	ProductController controller = mocks.PartialMock<ProductController>();
		controller.RenderView("index.aspx"); // <<-- Compiler error here, RenderView is protected!

	using (mocks.Playback())

Problem, part of the Rhino Mocks design goal was the use of the compiler and tools as verifiers. I explicitly do not want to have strings in my code, and I put them only where I have no other choice. However, since Rhino Mocks by runtime subclassing, there is no issue with reflection calls...

This means that we can get around this limitation by using the following extension method:

public static void RenderView(this Controller self, string action)
	typeof(Controller).GetMethod("RenderView").Invoke(self, new object[] { action} );

This is it, it will compile and work now.



Nice! I need to update my post with this technique.

Thomas Gravgaard

Just one slight change is needed to the code. The RenderView extension method has to look like this since the original method is protected. But is is still a very neat technique. Seems like MVC is drawing out a lot of the cool stuff you can do with extension methods:

    public static void RenderView(this Controller self, string action)



            System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic, 


            new Type[] { typeof(String) },


            ).Invoke(self, new object[] { action });

Grimace of Despair

Could someone hint the guys at Microsoft that their code "protection" through internal/private/protected members all over the place might just not be such a good idea in the light of extensibility?

John Chapman

This may sound like blasphemy, but why doesn't Rhino mocks just add the ability to reference a method by name instead of having to call the method when registering it in the framework in order to handle non-public members.

I love the way it works for public methods, but if I need to add an extension method and then use reflection to wire up my mock I may as well be using the framework instead since I'll have the weakly typed issues anyway.

I would just feel dirty using extension methods in this way. Plus it seems like extra unnecessary steps every time you need to do something like this.

Ayende Rahien


I am accepting patches :-)

H&#229;kan Forss

I'm a little into John's approach but with a twist.

Wouldn't it be possible to have Rhino mock expose all protected methods as public on creation of a partial mock

Ayende Rahien


But you won't get the compile time access to that, RhinoMocks works at run time.

Jimmy Bogard

Just curious, would you recommend this mechanism over something like "Subclass and override"? For example:

public class TestController : Controller


public new virtual void RenderView(string action)





Slightly more annoying, but with compile-time safety.

Vijay Santhanam

Haack has an interesting post on this topic:


He recommends the Test Specific Subclass if you have protected methods. I think he implies in his post that most protected virtual methods will become public to assist TDD - which would ideally solve this problem.

Comment preview

Comments have been closed on this topic.


No future posts left, oh my!


  1. Technical observations from my wife (3):
    13 Nov 2015 - Production issues
  2. Production postmortem (13):
    13 Nov 2015 - The case of the “it is slow on that machine (only)”
  3. Speaking (5):
    09 Nov 2015 - Community talk in Kiev, Ukraine–What does it take to be a good developer
  4. Find the bug (5):
    11 Sep 2015 - The concurrent memory buster
  5. Buffer allocation strategies (3):
    09 Sep 2015 - Bad usage patterns
View all series


Main feed Feed Stats
Comments feed   Comments Feed Stats