Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does one refer to a stub which has a generic parameter of itself using Microsoft Fakes?

I'm using Microsoft Fakes in some unit tests I'm working on. My interface looks like this:

interface ISecuredItem<TChildType> where TChildType : class, ISecuredItem<TChildType>
{
    SecurityDescriptor Descriptor { get; }
    IEnumerable<TChildType> Children { get; }
}

A typical implementation of this looks like:

class RegistryKey : ISecuredItem<RegistryKey>
{
    public SecurityDescriptor Descriptor { get; private set; }
    public IEnumerable<RegistryKey> Children { get; }
}

I'd like to use this interface with Microsoft Fakes, and have it generate a stub for me. The problem is, the form Fakes uses is StubInterfaceNameHere<>, so in the above example you end up trying to do something like StubISecuredItem<StubISecuredItem<StubISecuredItem<StubISecuredItem....

Is this possible? If so, how do I use Fakes in this way?

like image 944
Billy ONeal Avatar asked Oct 01 '12 20:10

Billy ONeal


People also ask

What is Microsoft Fakes?

Microsoft Fakes helps you isolate the code you're testing by replacing other parts of the application with stubs or shims. The stubs and shims are small pieces of code that are under the control of your tests.

What does add fakes Assembly do?

When you click on “Add Fakes Assembly” it will create the same assembly again with the Fakes keyword added that we will use for our testing purposes. The Fakes framework uses delegate-based methods for writing code.

What is a shim C#?

Shim, in C#, is a template class that is derived from a base class with derived classes that inherit the data and behavior of the base class and vary only in the type. The derived class of the shim class reuses the implementation provided by the shim class.


1 Answers

After some experimentation I found a working solution although it's not the most elegant.

This is your regular code:

public interface ISecuredItem<TChildType>
    where TChildType : ISecuredItem<TChildType>
{
    SecurityDescriptor Descriptor { get; }
    IEnumerable<TChildType> Children { get; }
}

In your test project you create a StubImplemtation interface

public interface StubImplemtation : ISecuredItem<StubImplemtation> { }

Then in your unit test you can do the following:

var securedItemStub = new StubISecuredItem<StubImplemtation>
                          {
                              ChildrenGet = () => new List<StubImplemtation>(),
                              DescriptorGet = () => new SecurityDescriptor()
                          };

var children = securedItemStub.ChildrenGet();
var descriptor = securedItemStub.DescriptorGet();

You can skip the whole StubImplementation and use RegistryKey if that's no problem.

like image 137
Wouter de Kort Avatar answered Oct 20 '22 01:10

Wouter de Kort