Posts From March 2018 - Musing, Rants & Jumbled Thoughts

Header Photo Credit: Lorenzo Cafaro (Creative Commons Zero License)

As I've been giving my Mocking .NET Without Hurting It's Feelings talk, I've referenced several mocking frameworks, but only really gave code examples for a couple of them. In part, this was because more than that would make the presentation chaotic, but also because I had only a very limited exposer (if any) to some of the frameworks.

So I decided to put together a GitHub repository where I implemented the same basic tests using different mocking frameworks in order to a) provide side-by-side examples of how to use the frameworks and b) go a little deeper with some of the frameworks I haven't used much.

While I had no problems with the frameworks I've used (Moq, RhinoMocks, etc), when it came time to write real code using Microsoft Fakes, I quickly ran into a wall. A key feature of the frameworks I've used is the ability to verify a specific mock/stub was or was not called. Generally, this is done through some sort of AssertWasCalled() or AssertWasNotCalled() helper. But for Fakes, this just didn't exist. The functionality is there, but getting to it is like walking barefoot through fire.

fire walker

Seriously, in order to do something like AssertWasCalled, you need to first include a StubObserver when you create your stub, which will capture calls and other info:

var myMock = new StubIFoo {InstanceObserver = new StubObserver()};

Then, to determine if a method was called, you have to inspect that observer:

Assert.IsTrue(((StubObserver)myMock.InstanceObserver).GetCalls().Any(call => call.StubbedMethod.Name == "MyMethod"));

And if you want to check if specific arguments were passed in, then it get's worse:

 var myCall = ((StubObserver)myMock.InstanceObserver).GetCalls().First(call => call.StubbedMethod.Name == "MyMethod");
 object[] argsToMyCall = myCall.GetArguments().ToArray();

Now I've got an un-typed object array to walk through and check. Eek!

After a couple of hours of internet research and stale Stack Overflow posts, I landed on a NuGet package called Fakes.Contrib which did all the heavy lifting for you and allowed you to add .AsObservable() to your stub, then call .AssertWasCalled as you would expect. It even provided type placeholders so you could do With.Any<MyClass>() if you didn't care about a specific argument. This was exactly what I wanted (and what I would have expected Microsoft to have provided out-of-the-box).

// Arrange
var obj = new MyClass();
var stub = new StubIMyComponent().AsObservable();
var sut = MakeSut(stub);

// Act

// Assert
stub.AssertWasCalled(mock => mock.MyMethod(With.Any<MyClass>()));

Now, I quickly ran into an issue: The Fakes.Contrib logic only worked on concreate classes. It didn't support using Interfaces, which my whole sample project was built with. But wait! It's Open Source! So I put together a pull request to add support for interfaces and reached out to the project owner Fabian Vilers to let him know it was coming. Fast forward a couple of weeks, and now I'm the primary owner of that project!

I'm not sure yet where this will go. I will add support here and there as I play with Microsoft Fakes, but since I don't have a project where I would use it extensively, I'm hoping to hear from people how do and get some feedback. If nothing else, it gives me some entry-level experience managing an open source project / nuget package.

You can checkout the Fakes.Contrib project on GitHub:

Or on NuGet