8

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?

Billy ONeal
  • 104,103
  • 58
  • 317
  • 552

1 Answers1

5

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.

Wouter de Kort
  • 39,090
  • 12
  • 84
  • 103
  • This will definitely do the trick, but it requires implementing the interface as a stub/mock in the test project. I don't know if that is the idea... – Damian Schenkelman Oct 06 '12 at 06:26
  • I can imagine it's not the idea.. but I couldn't see any other solution. When you look at the source code that the Fakes framework generates, the generic parameter is of type ISecuredItem, not of StubISecuredItem. I would almost say that's a bug in the framework. And the implementation in the test project can have all the methods throw a NotImplementedException so it shouldn't cost to much time to create. – Wouter de Kort Oct 06 '12 at 07:01
  • I kno, I totally agree. The answer solution that automatically came to my mind is the one you mentioned. – Damian Schenkelman Oct 06 '12 at 15:03
  • True, this works, but completely defeated the point of MS fakes. The point is not needing to explicitly implement a stub class... but I see what you mean here. – Billy ONeal Oct 08 '12 at 16:15
  • Yeah, I understand this is not the best solution. But you don't have to completely implement it! You can still stub each and every method and do whatever you want with it. I think this is the 'best' approach you will find. – Wouter de Kort Oct 08 '12 at 17:04
  • @BillyONeal I just realized that instead of using a 'NotImplemented' class, you can also use an interface in your test project. That way you don't need to implement any methods on your class. – Wouter de Kort Oct 09 '12 at 07:20