2

Is there any way to retrieve the fake objects which were inserted into a faked class?

E.g.

Let's say I have the following interface + class;

public interface IFakeable
{
    void FakeYou();
}

public class SomeClass
{
    private readonly IFakeable _fake;

    public SomeClass(IFakeable fake)
    {
        _fake = fake;
    }

    public void FakeCall()
    {
        _fake.FakeYou();
    }
}

And wanted to test something like the following:

[TestFixture]
public class SomeClassTests
{
    [Test]
    public void FakeCall_CallsIFakeabl_FakeYou()
    {
        var subject = A.Fake<SomeClass>();

        subject.FakeCall();

        A.CallTo(() => A.Fake<IFakeable>().FakeYou()).MustHaveHappened();
    }
}

Is this possible without exposing the SomeClass._fake field?

Is there somewhere I can specify to use Singletons for Fakes?

Michal Ciechan
  • 13,492
  • 11
  • 76
  • 118

2 Answers2

3

If the subject of the test is SomeClass, why are you faking it? You want to test the actual class, not a fake... So you should probably do this:

[Test]
public void FakeCall_CallsIFakeabl_FakeYou()
{
    var fake = A.Fake<IFakeable>();
    var subject = new SomeClass(fake);

    subject.FakeCall();

    A.CallTo(() => fake.FakeYou()).MustHaveHappened();
}

Alternatively, you could use FakeItEasy's fixture initialization feature:

[TestFixture]
public class SomeClassTests
{
    [Fake] public IFakeable Fake {get;set;}

    [UnderTest] public SomeClass Subject {get;set;}

    [SetUp]
    public void Setup()
    {
        Fake.InitializeFixture(this);
    }

    [Test]
    public void FakeCall_CallsIFakeabl_FakeYou()
    {
        Subject.FakeCall();

        A.CallTo(() => Fake.FakeYou()).MustHaveHappened();
    }
}
Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
1

What's more important here is why you're looking to test a method that is called on a private field. The private field is encapsulated in the class, therefore anything the method does on that field constitutes "internals of the class" and isn't relevant to testing. I presume that the FakeYou() implementation has some important side effect that requires testing. In that case, I would test for that side effect following the subject.FakeCall(), rather than testing that the FakeCall has happened.

Alternatively, you can change _fake to be a public field, and change:

A.CallTo(() => A.Fake<IFakeable>().FakeYou()).MustHaveHappened();

to:

A.CallTo(() => subject._fake.FakeYou()).MustHaveHappened();

You might want to rename "_fake" as "Fake" if this is the case for C# conventions, as ReSharper will tell you.

  • The reason I ask is, because often I want to check that for instance SaveChanges() is called on an EF Context. I found FakeItEasyAutoMocker which is the same what I created (Moqqer) for Moq. So guess there is no support for this out of the box. – Michal Ciechan Apr 28 '16 at 20:03