-2

Even though I've understood the principle of mocks, stubs and class abstraction for a testable design, there's something that's still very unclear to me.

Working with .NET, there are a lot of built-in classes, such as StackTrace for example, located under the Diagnostics namespace.
Some of those classes contain collections of other classes, and those classes contain other classes as well, etc. etc. etc... - The containment principle.
For example: The StackTrace class contains an array of StackFrame objects, which itself has a method returning a MethodBase object.

Say none of those classes are abstract, meaning they can't be mocked directly - How could one design the code to be able to mock those classes, without creating tons of wrapping classes and wasting a lot of crutial time on it?

I hope I'm clear enough on that one.

Timor Gruber
  • 312
  • 2
  • 4
  • 15
  • 5
    Why would you want to mock `StackTrace`? You typically mock *services* - not data objects such as `StackTrace` and `MethodBase`. (Likewise, you don't bother mocking collections, strings etc.) – Jon Skeet Feb 08 '17 at 14:05
  • @JonSkeet The `StackTrace` class has an abillity to read files internally (Which is an I/O, so it's a kind of a service), thus it has to be mocked to avoid a filesystem dependency. Please correct me if I'm wrong. – Timor Gruber Feb 08 '17 at 14:54
  • Only if you're using that aspect of them. – Jon Skeet Feb 08 '17 at 15:09
  • What you're after has very little practical value. 1) You shouldn't test other people's code 2) Your binaries reside somewhere on disk from where they run, your code will have read/write access there, no? So what's the problem with allowing `StackTrace` do its job? `StackTrace` exposes virtual methods, so to achieve what you're after you'll have to write your own class that inherits from `StackTrace` and override these methods. – Sherlock Feb 08 '17 at 15:32
  • 1
    Is this a practical or hypothetical question? If practical: what is you test case, and code? – Jocke Feb 08 '17 at 15:58
  • Thanks guys, you've helped me solve the issue for the given example. However, theoretically speaking, if I ever encounter a scenario like I've described (meaning there's no abstraction at all and I absolutely can't change the source code) - how should I tackle it? – Timor Gruber Feb 08 '17 at 17:36
  • @Sherlock I have no intention in testing other people's code, instead I'm trying to mock it in my tests as I should. – Timor Gruber Feb 08 '17 at 17:40
  • @Timor Gruber what's the rationale for mocking framework's code? What external aspects of that code you're trying to avoid/ignore? How about NOT calling that method at all and simply mock output it generates? – Sherlock Feb 08 '17 at 17:52
  • @Sherlock As I've already pointed out - The `StackTrace` class for example does some I/O operations on the file that's running the code. I'd like to remove this dependency in my unit tests, so I could generate a fake output, just as you've proposed. This requires mocking, or stubbing (which is the correct term for this case). Can you see where I'm getting at? – Timor Gruber Feb 08 '17 at 18:19
  • @TimorGruber if you must, just inherit from `StackTrace` and override `virtual` method(s) GetFrame(s) and return stubbed version of `StackFrame`. Additionally you may derive from `StackFrame` and override its virtual methods. I guess I don't understand why existing implementation of `StackTrace` that performs I/O operations is a problem. – Sherlock Feb 08 '17 at 18:41
  • @Sherlock As I see it (I'm still new to the subject) every object that makes any use of a system-dependent resource - should be abstracted and mocked/stubbed. The `StackTrace` and the `StackFrame` classes appear to be a bad example. However, if I encounter a scenario where an object has no virtual methods, and it does extensive use of system-dependent resources - What should I do to abstract this object and be able to mock/stub at least parts of it? – Timor Gruber Feb 08 '17 at 19:08
  • @TimorGruber take a look at [this](http://stackoverflow.com/questions/7299097/dynamically-replace-the-contents-of-a-c-sharp-method). What I don't get is what exactly you're trying to achieve. If you just need a sample output which doesn't need to be real, then mock/stub that structure. If you need the real output produced by real inner-workings of that method, yet want to omit/replace some implementation details, while such method doesn't export this capability (no interfaces/virtual methods) you're SOL. Then you have to resort to some black magic, which I referenced in this comment. – Sherlock Feb 08 '17 at 20:12

1 Answers1

0

Comments have led me to MSDN, where I've found out that this question has been asked due to a lack of a proper research.
All the methods I'm after are defined as virtual, thus CAN be mocked directly.

Note: This answers only the specific example given in the question

Timor Gruber
  • 312
  • 2
  • 4
  • 15