233

I am fairly new to unit testing in C# and learning to use Moq. Below is the class that I am trying to test.

class MyClass
{
    SomeClass someClass;
    public MyClass(SomeClass someClass)
    {
        this.someClass = someClass;     
    }

    public void MyMethod(string method)
    {
        method = "test"
        someClass.DoSomething(method);
    }   
}

class Someclass
{
    public DoSomething(string method)
    {
        // do something...
    }
}

Below is my TestClass:

class MyClassTest
{
    [TestMethod()]
    public void MyMethodTest()
    {
        string action="test";
        Mock<SomeClass> mockSomeClass = new Mock<SomeClass>();
        mockSomeClass.SetUp(a => a.DoSomething(action));
        MyClass myClass = new MyClass(mockSomeClass.Object);
        myClass.MyMethod(action);
        mockSomeClass.Verify(v => v.DoSomething(It.IsAny<string>()));
    }
}

I get the following exception:

Expected invocation on the mock at least once, but was never performed
No setups configured.
No invocations performed..

I just want to verify if the method "MyMethod" is being called or not. Am I missing something?

H. Pauwelyn
  • 13,575
  • 26
  • 81
  • 144
user591410
  • 3,051
  • 5
  • 21
  • 30
  • 1
    That won't compile if `SomeClass` doesn't have a definition for `MyMethod(string)`, which it looks like it doesn't. – Platinum Azure Feb 03 '12 at 23:08
  • sorry..I edited my question.. – user591410 Feb 03 '12 at 23:17
  • 1
    You're on the right track, but there are bugs in the posted code. It won't compile - casing on Someclass, void return on DoSomething. After that you need public access, then make DoSomething virtual. In short you probably have a bug in your production code too. – TrueWill Feb 04 '12 at 01:37
  • Thanks for your response. I was setting the arguments wrong while setting up the mock method.. – user591410 Feb 04 '12 at 17:43
  • "No setups configured." Could be misleading. You don't need to setup a behavior for methods that will be called. And also remember to execute "Verify" method AFTER the method you're testing should be called (so it's ok in your case). – Sielu May 18 '16 at 12:34

1 Answers1

357

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.

Platinum Azure
  • 45,269
  • 12
  • 110
  • 134
  • Sorry, I edited my question with the right method. As you mentioned, I tried SetUp first and then performed Verify. It still gives me the same exception. – user591410 Feb 03 '12 at 23:23
  • I updated my question with the suggestions that you made, but even this gives me the same exception.. Please advise. – user591410 Feb 03 '12 at 23:31
  • Got it.. Thanks.. I was setting the arguments of the method wrong while setting it up. – user591410 Feb 04 '12 at 17:43
  • 34
    Isn't it redundant to setup an expectation, then explicitly verify the same expectation? Wouldn't `mockSomeClass.VerifyAll();` achieve the same result and be more DRY? – Tim Long Feb 04 '12 at 19:04
  • 21
    Yes it would but some people favor being explicit. – Platinum Azure Feb 04 '12 at 19:53
  • 3
    Thanks for at least mentioning the VerifyAll(); while obvious once you think about it. I might have went for the explicit approach, but much cleaner when using the all. Thankful both are listed. – JGood Aug 10 '16 at 20:58
  • 2
    One related disadvantage of `Mock` compared to `NSubstitute` is that if you are trying to verify also the parameters and verification fails, it just shows what invocations were performed, but does not show what exactly was expected if you used variables in verification expression - it will just show variable name, not its value, so you'll need to debug to check what value exactly is that variable having. NSubstitute will just show values of both and even where it was different. – Grengas Feb 21 '20 at 08:51
  • 3
    @PlatinumAzure While setting up the mock object, `mockSomeClass.Setup(mock => mock.DoSomething());` , here I'm getting error that **There is no argument given**. The arguments are needed for the setup or not? – Tejashree Sep 28 '20 at 20:37
  • 3
    @Tejashree Yes, if your method has parameters then they must be specified in the mock setup, e.g.: `mockSomeClass.Setup(mock => mock.DoSomething(It.IsAny(), It.IsAny()));` Additionally in this scenario your Verify should specify the same parameters, e.g.: `mockSomeClass.Verify(mock => mock.DoSomething(It.IsAny(), It.IsAny()), Times.Once());` – JKH Mar 22 '21 at 14:42
  • 2
    I'm guessing that in @PlatinumAzure's example he explicitly tests that `DoSomething();` is called once only - more than one call to that method will fail the test. `VerifyAll();` it would not catch if `DoSomething();` is called more than one time, which will result in the test would succeed even in that case. – Moelbeck Nov 04 '21 at 07:02