Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my Moq claim no invocations are being thrown, yet it displays the thrown invocation in the exception?

I have the following unit test:

[TestMethod]
public void Execute_Sends_Email_To_User()
{
    // Setup
    InitializeTestEntities();
    _mock.Setup(x => x.Send(It.Is<string>(y => y == _user.Email), 
        It.IsAny<string>(), It.IsAny<string>()));

    // Act
    new ResetUserPasswordCommand(_unitOfWork, 
        _mock.Object).WithUserId(_user.Id).Execute();

    // Verify
    _mock.Verify(x => x.Send("", "", ""), Times.Once());
}

When this runs, I get the following exception message

Test method 
MyApp.Tests.Commands.Users.ResetUserPasswordCommandTests.Execute_Sends_Email_To_User 
threw exception: 

Moq.MockException: 
Expected invocation on the mock once, but was 0 times: x => x.Send("", "", "")

Configured setups:
x => x.Send(It.Is<String>(y => y == ._user.Email), It.IsAny<String>(), 
    It.IsAny<String>()), Times.Once

Performed invocations:
IEmailUtils.Send("[email protected]", "Password Recovery", 
    "Your new password is: 7Xb79Vb9Dt")

I'm confused about this, because it says that the mock was invoked 0 times, yet it shows that the successful invocation. What am I doing wrong?

like image 639
KallDrexx Avatar asked Mar 30 '11 04:03

KallDrexx


1 Answers

you need

_mock.Verify(x => x.Send(
     It.IsAny<String>(), It.IsAny<String>(), It.IsAny<String>(), Times.Once());

cause it does not match the arguments passed in. Therefore it thinks it didn't call that method with those arguments.

You can Verify that the specific strings are passed into the mock method, but that will depend on what you are trying to test

In your particular case there is no point to the Setup method as the Verify will still work. Only when you need to return a value from a mocked method do you really need to use Setup.

like image 138
aqwert Avatar answered Oct 06 '22 09:10

aqwert