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.

I've created a github repo with a set of example projects for several .NET Mocking Frameworks, to provide some apples-to-apples comparisons. Currently includes Moq, RhinoMocks, NSubstitue, MSFakes. More to come.
https://t.co/62ttMNDWC0

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.

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).

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 ownerFabian 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.

Loading Visualizers (and Where To Install)

Visualizers registered in assemblies currently loaded into the application will be available. That is, the DebuggerVisualizer
attribute must have been loaded and the assembly housing the visualizer must be loaded (otherwise you'll get an error message
from Visual Studio saying it couldn't find the assembly).

If the visualizers are included in projects in the currently loaded solution, typically everything "just works". However,
if the visualizers are in a seperate assembly (not part of the current solution) which you reference, you may need to
force the assembly to be loaded. If you use the actual type in the DebuggerVisualizer attribute (ex: [DebuggerVisualizer(typeof(SomeTypeVisualizer))]),
that should be enough. But if you use the string-based constructor for the attribute (ex: [DebuggerVisualizer("MyVisualizers.SomeTypeVisualizer")]),
you may need to force the assembly to be loaded. One way to do that is add a static constructor to your main class that references
a type from the visualizer assembly, like this:

This, however, makes it pretty difficult to include standalone visualizers in NuGet packages. (Though, including visualizers in the
assembly with the types they visualize would work via NuGet)

The more common approach is to install the assembly with your visualizers into one of two places:

<VisualStudioInstallPath>\Common7\Packages\Debugger\Visualizers\ to make them available to all users on the computer.

My Documents\<VisualStudioVersion>\Visualizers\ to make them available to the current user.

Note: The visualizers must be installed on the machine running the application being debugged, so if you're using
a remote debugging session, they must be installed on the remote machine as well as your local machine.

You can find a number of visualizers in the Visual Studio Marketplace, and they'll install into one of these locations.

Security Considerations

Keep in mind that parts of the Debugger Visualizer effectively run with the security level of Visual Studio, and all too many of us developers run Visual Studio as Administrator (thanks, in large part, to the crazy that is IIS's security model). So that means the visualizer you select could happily go off and delete your entire hard drive, send all of your source code to an FTP site, or whatever Hollywood-style hacker-in-a-hoodie nefarious stuff you can imagine.

So make sure you know and trust the source for any visualizers you choose to run. And since visualizers can been shipped with libraries you're using, they may be available without you having directly installed anything.

Visual Studio already has some safeguards in place, such as disallowing app-side VisualizerObjectSource object running in partial-trust. But, in my experience, very few of us make use of anything but full-trust environments. So Don't Be Stupid and pay a little extra attention to which visualizers you see vs. what you expect to see listed.

Supported Types and Limitations

Generics have very poor support. You can only register a visualizer with an open generic type
(ex: Dictionary<,>) but not a constructed type (ex: Dictionary<int, string>). But in the visualizer, you only get an object,
so without a lot of crazy reflection, you have no way of knowing the types used in the generic placeholders.

Universal Windows Platform (UWP) apps and Windows "Store" apps do not support custom visualizers, though they can use
the built-in string visualizers (Text, HTML, XML, JSON).

The visualizers described in this post only work for managed code. Native VisualCpp assemblies won't use them.

Making Your Visualizer Editable

There are cases where just viewing data from the object you're visualizing during a debugging session isn't enough. You'd like to modify the object in some way. Perhaps to setup a specific failure/success scenario or replicate a bug/bug fix.

If you're using a read-only visualizer, like what we've built so far in this series, you'd need to close the visualizer and use the Immediate Window to modify the data. Particularly if the value you want to modify is deeply nested in your object graph, or you have a bunch of items in a child collection and finding the right one to modify is tedious, then using the Immediate Window can be an exercise in frustration.

Luckily, the Debugger Visualizer API allows a great amount of flexibility to modify the object we're visualizing.

The Components Involved

Going from a read-only visualizer to one that can modify/interact with the underlying object means taking advantage of additional methods in the IVisualizerObjectProvider and VisualizerObjectSource.

Specially, in IVisualizerObjectProvider, you can call ReplaceData/ReplaceObject or TransferData/TransferObject to request changes to the live object. Just like the GetData/GetObject calls we discussed in earlier posts, the "Data" versions of the methods work against Stream objects and you must serialize/deserialize the values yourself, while the "Object" methods will call the "Data" method, then automatically serialize/deserialize for you.

Calls to IVisualizerObjectProvider.ReplaceData result in a call to VisualObjectSource.CreateReplacementObject on the app side. The intention of this API is to completely replace the live object with the version being passed into the ReplaceData call. If the object being visualized is Serializable, you can use the default implementation of VisualizerObjectSource.CreateReplacementObject, which will deserialize the incoming Stream and return the object as the new version. Otherwise, you'll need to write your own class that extends VisualizerObjectSource and overrides CreateReplacementObject to take in the Stream coming from the Visual Studio side (which could be a ViewModel object if the primary object isn't serializable) and convert it into an instance of the Type being visualized to replace the current object.

Additionally, you'll need to first verify that IVisualizerObjectProvider.IsObjectReplaceable is true. Otherwise, you won't be allowed to manipulate the object via the ReplaceData method. Documentation on when this would be false is scarce, but I did find this summary block for the property in a Patent filing for this feature:

public interface IVisualizerObjectProvider
{
/// <summary>
/// Specifies whether a replacement object can be created. For instance, if the object being
/// visualized is a readonly field then this will return false.
/// </summary>
/// <returns></returns>
bool IsObjectReplaceable { get; }

Alternatively, you can use the TransferData method to send any arbitrary data stream from your visualizer to the VisualizerObjectSource.TransferData method. With this pair of methods, you can send serialized data from the Visual Studio side to the application side, and optionally have it reply back with a serialized object. This opens up the possibly of implementing a messaging system between the two side for more complex interactions.

For instance, in the case of a WebException, you could decide to use the actual WebException type in the GetData call, then, should the user click a button on the UI to review the response HTML, you could send a message to the application via the TransferData call, have it read the WebExceptionResponse.GetResponseStream() Stream and return the string version of the output.

NOTE: Communication is always initiated by the Visual Studio side -- specifically, calls from your Visualizer class into IVisualizerObjectProvider. The application-side cannot initiate the conversation and TransferData is the only method where it can return something other than the object being used by your visualizer.

The Logical Flow (For Modifying an Object from Your Visualizer)

The initial flow for getting data into your visualizer will remain the same (see the previous posts in this series). But once visualized, users can then interact with your UI to initiate changes to the object. Generally, this will be via OnChange-type events in your object/ViewModel or button click UI events that are handled by your Visualizer class. Thus, any changes or actions the user makes via the UI will be picked up by your Visualizer class.

Then, from your handler, you need to decide which API you want to use.

The simpler path would be to modify the version of the object you already have in memory (or have the UI bound directly to the object so it is automatically updated on changes), then call ReplaceObject with the updated object.

Otherwise, you can call TransferObject with some object of your choosing, such as a messaging DTO you've created that holds the action or changes you want to pass to the application.

This, in turn, will call the corresponding method in VisualizerObjectSource.

If you used ReplaceData or ReplaceObject, your implementation of CreateReplacementObject is called with the current object instance and the Stream of the serialized object coming from the IVisualizerObjectProvider. That method will need to take the incoming Stream and return an object. When the method returns the object, it will replace the original object in the applications memory.

If you used TransferData or TransferObject, your implementation of TransferData will be called. You cannot use the base implementation of TransferData -- it will just throw NotImplementedException). There are three parameters passed into VisualizerObjectSource.TransferData:

The original object being visualized

An incoming Stream for the data being passed from the visualizer TransferData

An outgoing Stream to allow a reply back to TransferData

The key for using TransferData is to have both sides of the call to have a common understanding of the types being passed around so that they can be deserialized/cast to the appropriate object Type rather than just object. Then it's just a matter of determining what data needs to be modified or what action needs to be taken and acting accordingly. Ultimately, the TransferData method needs to modify the passed-in original object if changes are needed.

In that case where TransferData is used, the third parameter passed into the VisualizerObjectSource.TransferData method is an outgoing Stream. This allows for a response to be returned to the Visualizer via the IVisualizerObjectProvider.TransferData's return value. For TransferData, the return value is a Stream which you must deserialize yourself, or if you used TransferObject, it's an object that you must cast to the appropriate Type. So again, having an common understanding of the types being transferred is key.

An example of how this might be used:

For a WebResponse visualizer, if you need the actual response value, you could call IVisualizerObjectProvider.TransferData with a message object requesting the actual response value. Then your VisualizerObjectSource.TransferData, upon decoding the message, would call Response.GetResponseStream() and read the response into a string object. Then, that string could be returned on the outgoing Stream. Then, the visualizer would receive the string as the return value of it's call to TransferData, and update the UI to display the string value.

The VisualizerObjectSource

TIP: If you use ReplaceData/ReplaceObject and you're passing the actual type being visualized (not a ViewModel), then you don't actually need to implement your own VisualizerObjectSource and/or override CreateReplacementObject, as the base implementation will just deserialize the passed-in object and replace the live object with the new version.

Otherwise, you'll override the CreateReplacementObject method to handle the conversion process. If you're passing a ViewModel into TransferData, then CreateReplacementObject will need to map the ViewModel's values into either a new instance of the type being visualized, or modify the original object (which is passed in as a parameter). Ultimately, the CreateReplacementObject call must return an object which will replace the live object being visualized in the application's memory.

WARNING: When using the ReplaceData calls, be aware of object pointers in your object and make sure you wire the pointers back up correctly. The serialization process may result in new objects being created as clones of your original objects and you'll need to use the CreateReplacementObject method to replace those with the original objects pointed to in your object graph.

public override object CreateReplacementObject(object target, Stream incomingData)
{
var originalObject = target as SimpleExample.SomeType;
var incomingChangedObject = Deserialize(incomingData) as SimpleExample.SomeType;
// if this is a ViewModel, you'll need to map the value into either a new instance of
// the visualized type, or modify the originalObject with the ViewModel's values and return
// the originalObject as the new instance.
// Beware object pointers! If you have an object graph or other data types which will result in
// cloned objects being created during the serialization/deserialization process, you'll need to
// handle that here.
//returns a instance of the object, which VS will substitute for the original object in memory
return incomingChangedObject;
}

If you've used the TransferData/TransferObject, you must override the VisualizerObjectSource.TransferData method. As parameters, the method will receive the original object being visualized, the incoming Stream being sent from the IVisualizerObjectProvider, and an outbound Stream which can be used to send response messages/data back to the Visualizer.

The Visualizer

For the visualizer in this simple example, I'm registering an OnChange event handler for the TextBox displaying the Foo property (the only property shown in this example) and I've removed the Readonly attribute on the textbox to allow the user to edit the value. I'm using in-line delegates as my handler, but you could just as well register explicit methods.

I'm including both approaches in this code sample, but you'll want to use one or the other, not both.

Using WPF for the UI

Ok, so far my UIs have been pretty basic, but as I start to visualize more complex object types, I'm going to need more complex UIs. And personally, I find that hard to do with WinForms. Plus, I'd rather use MVVM-style UI binding instead of the code-behind style typical with WinForms. So, I want to use WPF for my UI instead of WinForms.

Thankfully, this is super easy to do!

I'll use the same ViewModel and VizualizerObjectSource as I did for my WinForms visualizer, but on the Visual Studio side, I'll have a different UI and a different Visualizer class:

The UI

Obviously, the UI will be WPF-based now. I'll use DataContext binding in my XAML to bind directly against my ViewModel class.

The Visualizer

The other change that's needed to use WPF is to the Visualizer. Instead of using the passed-in IDialogVisualizerService to show a dialog, we'll create an instance of a WPF Window, put our WPF UserControl on it, and show that window.