4

My question is about the technical reason for this limitation, not about how to fix it.

Why do some frameworks like Telerik JustMock and Typemock Isolator support these features, but we can not have these in Moq or FakeItEasy or NSubstitute, etc.?

Are the items mentioned unnecessary in unit testing?

Heretic Monkey
  • 11,687
  • 7
  • 53
  • 122
HamedFathi
  • 3,667
  • 5
  • 32
  • 72
  • 2
    "put on hold as primarily opinion-based": it's not opinion-based. There's a real technical reason, and it's a legitimate question. – Thomas Levesque May 22 '19 at 08:34
  • 2
    In addition to Thomas' excellent answer, here is a bit more info on [how NSubstitute works](https://nsubstitute.github.io/help/how-nsub-works/) (Moq and FIE work similarly using Castle DynamicProxy). – David Tchepak May 23 '19 at 00:51

1 Answers1

8

This is because of the way these libraries work. When you mock a class using Moq, NSubstitute or FakeItEasy, they dynamically create a class that inherits from that class and overrides its methods. But they have to follow the platform's rules for overriding methods:

  • non-virtual methods can't be overridden, by definition
  • private methods are not accessible to derived classes, so they can't be overriden (and in fact, C# doesn't even allow them to be virtual, as it wouldn't make sense)
  • static methods can't be overridden either, because it wouldn't make sense: polymorphism is based on the type of the instance on which you call the method, and static methods don't have an instance...

In fact, these mocking libraries do nothing that you couldn't have done yourself by manually writing fake/mock classes; they just make it easier by relieving you of the boilerplate code. You couldn't manually override a static or non-virtual method, and these libraries can't do it either, for the same reason.

I don't know how JustMock and TypeMock Isolator work; I suspect they do some dark magic with the CLR's internals, or maybe dynamically rewrite code (that's what Pose does: it replaces calls to the specified methods with calls to replacement methods).

EDIT: See this question about how TypeMock Isolator works. It uses the profiler API to hijack method calls. As I said, dark magic ^^

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • Unfortunately, `Pose` does now work with extension methods. https://github.com/tonerdo/pose/issues/22 This library is awesome but not up to date and full-featured. – HamedFathi May 22 '19 at 18:06