3

I have an interface

public interface IInterface { void DoSomething(); }

Another interface

public interface IOtherInterface : IInterface { }

An abstract class

public abstract class AbstractClass : IInterface
{
    public void DoSomething()
    {
        Console.WriteLine("Got here");
    }
}

I'm writing a unit test and fake IOtherInterface. The abstract class already contains helpful methods I'd want to leverage for my unit test. How would I make my A.Fake<IOtherInterface>(); inherit from AbstractClass?

This is what I've tried so far but it doesn't work - AbstractClass.DoSomething does not get hit.

        IOtherInterface fake = A.Fake<IOtherInterface>(builder => builder.Implements(typeof (AbstractClass)));

        fake.DoSomething();

Of course if I make a proxy like:

        var abstractFake = A.Fake<AbstractClass>();
        A.CallTo(() => fake.DoSomething()).Invokes(abstractFake.DoSomething);

        fake.DoSomething();

... things work as I wanted. Is there a built in mechanism to achieve this so that I don't need that proxy abstractFake object?

UPDATE

I need IOtherInterface because I have a client class that needs that IOtherInterface as dependency:

class Consumer
{
    public Consumer(IOtherInterface otherInterface)
    {
        otherInterface.DoSomething();
    }
}
johnildergleidisson
  • 2,087
  • 3
  • 30
  • 50
  • It does, however `abstractFake` variable will be of type `AbstractClass` and not `IOtherInterface`. I need `IOtherInterface`. See update :) – johnildergleidisson Feb 24 '15 at 14:40
  • Thanks for raising this question. As you can see from Blair Conrad's answer, two project issues have been raised as a result, which is great! – Adam Ralph Feb 26 '15 at 06:52
  • @AdamRalph I'll be honest, it blew my mind to see the Blair's pro activity by going and creating those project issues, something you normally don't see. Normally even collaborators of a project would just say "go file a bug" of sorts. Anyway, I'm glad I have indirectly contributed :) – johnildergleidisson Feb 26 '15 at 14:27
  • Indeed, Blair Conrad is a huge asset to any project! – Adam Ralph Feb 28 '15 at 14:50

1 Answers1

5
var fake = (IOtherInterface) A.Fake<AbstractClass>(builder =>
                               builder.Implements(typeof(IOtherInterface)));
A.CallTo(() => fake.DoSomething()).CallsBaseMethod();
fake.DoSomething();

Implements is intended to work only with interfaces, so the proper way to use it is to fake an interface or class and use Implements to add additional interface. I think it should've complained at you, so I raised complain when IFakeOptionsBuilder.Implements is passed a non-interface, which was fixed in FakeItEasy 2.0.0.

The CallsBaseMethod will ensure that the Abstract class's method is executed.

I would've recommended builder.CallsBaseMethods(), but this fails to redirect the call. I think it's because it's redirecting AbstractClass.DoSomething, but when we cast the fake to IOtherInterface and call DoSomething, it's not matching. I've raised investigate interaction between Implements and CallsBaseMethods.

Blair Conrad
  • 233,004
  • 25
  • 132
  • 111
  • 1
    Thanks @blairconrad for helping, for being proactive raising the complaint/investigation. I'm not aware of the release cycle of FakeItEasy but I'm looking forward for these issues to be fixed. :) – johnildergleidisson Feb 24 '15 at 15:41
  • 2
    @JoaoMilasch, FakeItEasy usually [releases frequently](https://www.nuget.org/packages/FakeItEasy), but as with many open source projects, the schedule depends on the availability of the core team and rate of contributions from the community. I wouldn't necessarily expect a _speedy_ resolution, as the core team are involved in the upcoming 2.0 release, and these issues are quite minor. One is effectively "add a warning message to let users know they used Implements wrong" and the other is quite a corner case-an interaction between two not minor features, and it has a workaround. – Blair Conrad Feb 25 '15 at 11:33
  • fair enough. I'm ok with the work around anyway. Thanks for helping. – johnildergleidisson Feb 25 '15 at 13:59