9

Most mocking frameworks only are capable of mocking interfaces, some can mock virtual methods of classes. Some Java mocking frameworks are even capable of mocking static classes.

E.g. Rhino mock:

var mock = MockRepository.GenerateMock<..>();

What 'magic' goes down in the generate mock method? Is there a reason why C# mocking frameworks do not allow mocking static classes? Or is that just a 'design choice'?

bas
  • 13,550
  • 20
  • 69
  • 146
  • PS: googling the topic only gives me tutorials how to use a mocking framework, not what I am looking for – bas Mar 18 '13 at 20:25
  • try "ooo look at me *waving hands in the air* I'm a framework...ooo so special" :) – Eonasdan Mar 18 '13 at 20:30
  • 2
    [moq](https://code.google.com/p/moq/) is open source. – Austin Salonen Mar 18 '13 at 20:31
  • Usually the mock is an instance of a class, and therefore wouldn't make sense for it to be a static class, since they don't have instances. The technique to generate the static mock would probably be quite different as a result. Therefore, support for static classes would probably require different API and additional effort to support in the same framework. That is my educated guess. – AaronLS Mar 18 '13 at 20:40

3 Answers3

5

It is actually very fun and fascinating to look into the source code of such frameworks and find the answer yourself. Rhino Mocks is open-source, as well as Moq and many others. I would definitely recommend diving into one of those.

As for internal implementation (from here):

However, the framework can't mock non-virtual methods, so we'd need to make TouchIron method virtual. The reason for that lies deep inside: Rhino Mocks uses Castle Dynamic Proxy to handle proxying the types it needs to mock, and Dynamic Proxy cannot intercept calls to non-virtual, non-abstract methods.

Community
  • 1
  • 1
Alexander Tsvetkov
  • 1,649
  • 14
  • 24
  • That probably explains why static classes are not supported, as it'd have no way to redirect/proxy the static method calls. A completely different approach would probably be needed. – AaronLS Mar 18 '13 at 20:43
  • yo thx a lot, reading through stuff atm and trying to find the "download source" button on Moq :). thx so far, will be back later – bas Mar 18 '13 at 20:47
4

Most of the open-source mocking frameworks use Castle Windsor's Dynamic Proxy to automatically generate a type at runtime, that can be programmed with expected behavior. This is why most of those frameworks require having an interface or an abstract class - they are unable to mock anything that is not a virtual method.

There exist other (commercial) mocking frameworks that indeed can mock static and regular (sealed) classes, including CLR types, which are based on the unmanaged CLR Profiler API. Basically, the mocking framework acts as a profiler, and is able to modify the MSIL instructions in memory just before the JIT compilation. This is how it's able to replace the body of any method with predefined values. Some of those frameworks are free* (Microsoft Fakes, part of Visual Studio 2012 Ultimate), others are paid products, such as Typemock.

Igal Tabachnik
  • 31,174
  • 15
  • 92
  • 157
1

Almost all of the .NET mocking frameworks take advantage of Castle Windsor's Dynamic Proxy functionality. I would recommend going through some of that.

Shlomo
  • 14,102
  • 3
  • 28
  • 43