Search code examples
.netasp.netmockingmoqrhino-mocks

Can someone please clarify my understanding of a mock's Verify concept?


I'm playing around with some unit tests and mocking. I'm trying to verify that some code, in my method, has been called. I don't think I understand the Verify part of mocking right, because I can only ever Verify main method .. which is silly because that is what I Act upon anyways.

I'm trying to test that my logic is working - so I thought I use Verify to see that certain steps in the method have been reached and enacted upon.

Lets use this example to highlight what I am doing wrong.

public interface IAuthenticationService
{
    bool Authenticate(string username, string password);
    SignOut();
}

public class FormsAuthenticationService : IAuthenticationService
{
    public bool Authenticate(string username, string password)
    {
        var user = _userService.FindSingle(x => x.UserName == username);
        if (user == null) return false;

        // Hash their password.
        var hashedPassword = EncodePassword(password, user.PasswordSalt);

        if (!hashedPassword.Equals(password, StringComparison.InvariantCulture))
            return false;

        FormsAuthentication.SetAuthCookie(userName, true);
        return true;
    }
}

So now, I wish to verify that

  • EncodePassword was called.
  • FormsAuthentication.SetAuthCookie(..) was called.

Now, I don't care about the implimentations of both of those. And more importantly, I do not want to test those methods. That has to be handled elsewhere. What I though I should do is Verify that those methods were called and .. if possible ... an expected result was returned.

Is this the correct understanding of what 'Verify' means with mocking?

If so, can someone show me how I can do this. Preferable with moq but i'm happy with anything.


Solution

  • As I see it, you have two problems:

    1. EncodePassword belongs to the FormsAuthenticationService, which makes it harder to mock. There are two possible solutions to this problem:

      1. Make EncodePassword protected virtual, and create Mock<FormsAuthenticationService>. In this case you should be able to Verify EncodePassword.
      2. Extract password encoding into a different service, since it is not coupled to authentication implementation anyway.
    2. FormsAuthentication.SetAuthCookie(..) is a static method. One reasonable solution here is to use an additional service that completely wraps FormsAuthentication, but does not do anything beyond that, so you will not have to test it.