Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Moq to Verify if either method was called

I am trying to write a test that verifies that either Foo or FooAsync were called. I don't care which one, but I need to make sure at least one of those methods were called.

Is it possible to get Verify to do this?

So I have:

public interface IExample
{
    void Foo();
    Task FooAsync();
}

public class Thing
{
    public Thing(IExample example) 
    {
        if (DateTime.Now.Hours > 5)
           example.Foo();
        else
           example.FooAsync().Wait();
    }
}

If I try to write a test:

[TestFixture]
public class Test
{
    [Test]
    public void VerifyFooOrFooAsyncCalled()
    {
        var mockExample = new Mock<IExample>();

        new Thing(mockExample.Object);

        //use mockExample to verify either Foo() or FooAsync() was called
        //is there a better way to do this then to catch the exception???

        try
        {
            mockExample.Verify(e => e.Foo());
        }
        catch
        {
            mockExample.Verify(e => e.FooAsync();
        }
    }
}

I could try and catch the assertion exception, but that seems like a really odd work around. Is there an extension method for moq that would do this for me? Or is there anyway to get the method invocation count?

like image 468
Philip Pittle Avatar asked Jan 10 '18 10:01

Philip Pittle


People also ask

How do you know if mocked method called?

Mockito verify() method can be used to test number of method invocations too. We can test exact number of times, at least once, at least, at most number of invocation times for a mocked method.

What is verifiable in MOQ?

Verifiable(); 'Setup' mocks a method and 'Returns' specify what the mocked method should return. 'Verifiable' marks this expectation to verified at the end when Verify or VerifyAll is called i.e. whether AddIncomePeriod was called with an object of IncomePeriod and if it returned the same output.

What can be mocked with MOQ?

Moq can be used to mock both classes and interfaces.


1 Answers

You can create setups for the methods and add callbacks for them, then use that to set a boolean to test.

e.g. something like:

var mockExample = new Mock<IExample>();

var hasBeenCalled = false;
mockExample.Setup(e => e.Foo()).Callback(() => hasBeenCalled = true);
mockExample.Setup(e => e.FooAsync()).Callback(() => hasBeenCalled = true);

new Thing(mockExample.Object);

Assert.IsTrue(hasBeenCalled);
like image 75
Owen Pauling Avatar answered Oct 14 '22 17:10

Owen Pauling