Using Moq to Determine If a Method Is Called

Verify a method call using Moq

You're checking the wrong method. Moq requires that you Setup (and then optionally Verify) the method in the dependency class.

You should be doing something more like this:

class MyClassTest
{
[TestMethod]
public void MyMethodTest()
{
string action = "test";
Mock<SomeClass> mockSomeClass = new Mock<SomeClass>();

mockSomeClass.Setup(mock => mock.DoSomething());

MyClass myClass = new MyClass(mockSomeClass.Object);
myClass.MyMethod(action);

// Explicitly verify each expectation...
mockSomeClass.Verify(mock => mock.DoSomething(), Times.Once());

// ...or verify everything.
// mockSomeClass.VerifyAll();
}
}

In other words, you are verifying that calling MyClass#MyMethod, your class will definitely call SomeClass#DoSomething once in that process. Note that you don't need the Times argument; I was just demonstrating its value.

Using Moq to determine if a method is called

You can see if a method in something you have mocked has been called by using Verify, e.g.:

static void Main(string[] args)
{
Mock<ITest> mock = new Mock<ITest>();

ClassBeingTested testedClass = new ClassBeingTested();
testedClass.WorkMethod(mock.Object);

mock.Verify(m => m.MethodToCheckIfCalled());
}

class ClassBeingTested
{
public void WorkMethod(ITest test)
{
//test.MethodToCheckIfCalled();
}
}

public interface ITest
{
void MethodToCheckIfCalled();
}

If the line is left commented it will throw a MockException when you call Verify. If it is uncommented it will pass.

Using Moq to see if method was called with a value

You can simply use Verify method on your mock:

MyServiceMock.Verify(x => x.SendMail("SOME VALUE"), Times.Once());

Edit:

If you want to verify whether the text passed as a parameter does not matches exactly, but just contains the tested value, you can use, as Scott Chamberlain wrote:

MyServiceMock.Verify(x => x.SendMail(It.Is<string>(s => s.Contains("SOME VALUE")), Times.Once());

Use Moq to Verify if either method was called

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);

How do I verify a method was called exactly once with Moq?

You can use Times.Once(), or Times.Exactly(1):

mockContext.Verify(x => x.SaveChanges(), Times.Once());
mockContext.Verify(x => x.SaveChanges(), Times.Exactly(1));

Here are the methods on the Times class:

  • AtLeast - Specifies that a mocked method should be invoked times times as minimum.
  • AtLeastOnce - Specifies that a mocked method should be invoked one time as minimum.
  • AtMost - Specifies that a mocked method should be invoked times time as maximum.
  • AtMostOnce - Specifies that a mocked method should be invoked one time as maximum.
  • Between - Specifies that a mocked method should be invoked between from and to times.
  • Exactly - Specifies that a mocked method should be invoked exactly times times.
  • Never - Specifies that a mocked method should not be invoked.
  • Once - Specifies that a mocked method should be invoked exactly one time.

Just remember that they are method calls; I kept getting tripped up, thinking they were properties and forgetting the parentheses.

C# and Moq: How to validate an instance method is calling the proper secondary instance method?

The point is that what you're asking for is not what you should be doing. Yes, mocking framework can verify method calls, on mocks. You mock dependencies.

You don't have a dependency, you want to test that a method on the class you want to test calls another method on the class you want to test.

That's not what mocking nor unit testing are for, you're doing the wrong thing here. A method calling another method on the same class is an implementation detail, and not something that you should test. What matters is the output of the method, or the state of the object after the method call. Test that.

See for example How to use Moq in unit test that calls another method in same class.



Related Topics



Leave a reply



Submit