I really appreciate Moq\'s Loose
mocking behaviour that returns default values when no expectations are set. It\'s convenient and saves me code, and it also act
There is a way to call the real method and have a call back when the method is void
, but it's really hacky. You have to make your call back call it explicitly and trick Moq into calling the real one.
For example, given this class
public class MyInt
{
public bool CalledBlah { get; private set; }
public virtual void Blah()
{
this.CalledBlah = true;
}
}
You can write your test this way:
[Test]
public void Test_MyRealBlah()
{
Mock m = new Mock();
m.CallBase = true;
bool calledBlah = false;
m.When(() => !calledBlah)
.Setup(i => i.Blah())
.Callback(() => { calledBlah = true; m.Object.Blah(); })
.Verifiable();
m.Object.Blah();
Assert.IsTrue(m.Object.CalledBlah);
m.VerifyAll();
}
The key aspect is that you track if the fake version has been called, and then you set the mock up to not call the fake if it's already been called.
You can still do something similar if you take args and the value matters:
public class MyInt
{
public List CalledBlahArgs { get; private set; }
public MyInt()
{
this.CalledBlahArgs = new List();
}
public virtual void Blah(int a)
{
this.CalledBlahArgs.Add(a);
}
}
[Test]
public void Test_UpdateQueuedGroups_testmockcallback()
{
Mock m = new Mock();
m.CallBase = true;
List fakeBlahArgs = new List();
m.Setup(i => i.Blah(It.Is(a => !fakeBlahArgs.Contains(a))))
.Callback((a) => { fakeBlahArgs.Add(a); m.Object.Blah(a); })
.Verifiable();
m.Object.Blah(1);
Assert.AreEqual(1, m.Object.CalledBlahArgs.Single());
m.Verify(b => b.Blah(It.Is(id => 1 == id)));
}