Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FakeItEasy: Reset Fake Calls History / Ignore Call

I would like to reset a Fake Calls History or ignore a Call.

The fake asserted method is called in the Init method in the tested class constructor and I want to ignore this call because it's not part of the tested action.

Here an example:

[TestClass]
public class UnitTest1
{
    private MyFakedClass myFakedObject;
    private SUT sut;

    [TestInitialize]
    public void Init()
    {
        myFakedObject = A.Fake<MyFakedClass>();
        sut = new SUT(myFakedObject); //constructor calls myFakedObject.AssertedMethod()
    }

    [TestMethod]
    public void TestMethod1()
    {
        sut.TestedMethod(); //TestedMethod calls myFakedObject.AssertedMethod() again...
        A.CallTo(() => myFakedObject.AssertedMethod()).MustHaveHappened(Repeated.Exactly.Once); 
//...So this is false
    }
}
like image 821
maxence51 Avatar asked Mar 17 '15 09:03

maxence51


2 Answers

I love @forsvarir's answer. I would be inclined to think that the call from within the constructor is significant.

However, if you really need to do this:

When FakeItEasy version ≥ 3.2.0, you can use ClearRecordedCalls:

Fake.ClearRecordedCalls(fake);

When 2.0.0 ≤ FakeItEasy version < 3.2.0, consider the forsvarir's subtraction method (FakeItEasy: Reset Fake Calls History / Ignore Call).

When FakeItEasy version < 2.0.0, you can use scopes:

[Test]
public void TestMethod1()
{
    using (Fake.CreateScope())
    {
        sut.TestedMethod(); // calls myFakedObject.AssertedMethod() again
        A.CallTo(() => myFakedObject.AssertedMethod())
         .MustHaveHappened(Repeated.Exactly.Once);
    }
}

Using the scope causes MustHaveHappened to look only at calls made from within the scope.

You could also create the scope in the TestInitialize and dispose of it in the TestCleanup method, if you wanted to keep the using outside of all your test methods.

like image 82
Blair Conrad Avatar answered Nov 17 '22 19:11

Blair Conrad


This feels wrong to me. Typically I would expect the cost of object creation to be part of the expectations of the tests for that object. Obviously, it depends upon what your AssertedMethod does, however, would your test really still be valid if your constructor didn’t call it? Would your SUT be in the expected state that your class needs?

I can’t see anything in the fakeiteasy framework to allow you to reset the count, although as I’ve said, this doesn’t feel like the right thing to do so I wasn’t really expecting to find it. It seems like a simple way to achieve what you seem to be trying to do, whilst still acknowledging at least at a TestClass level that you know there is a call in the constructor/init would be something like this:

const int InitAssertedMethodCalls = 1;

[TestMethod]
public void TestMethod1()
{
    sut.TestedMethod(); 
    A.CallTo(() => myFakedObject.AssertedMethod())
             .MustHaveHappened(Repeated.Exactly.Times(1 + InitAssertedMethodCalls )); 
}
like image 23
forsvarir Avatar answered Nov 17 '22 18:11

forsvarir