views:

409

answers:

1

I'm trying to use Rhinomocks 3.5 and the new lambda notation to mock some tests. I've read this, but have so many more questions. Are there any complete examples out there, especially for a MVC type of architecture?

For example what is the best way to mock this.

 public void OnAuthenticateUnitAccount()
 {
  if(AuthenticateUnitAccount != null)
  {
   int accountID = int.Parse(_view.GetAccountID());
   int securityCode = int.Parse(_view.GetSecurityCode());
   AuthenticateUnitAccount(accountID, securityCode);
  }
 }

There is a view interface and a presenter interface. It's calling an event on the controller.

What I came up with is this.

[TestMethod()]
 public void OnAuthenticateUnitAccountTest()
 {
  IAuthenticationView view = MockRepository.GenerateStub<IAuthenticationView>();
  IAuthenticationPresenter target = MockRepository.GenerateMock<IAuthenticationPresenter>();

  target.Raise(x => x.AuthenticateUnitAccount += null, view.GetPlayerID(), view.GetSecurityCode());
  target.VerifyAllExpectations();
 }

It passes but I don't know if it is correct.

And yes we are doing the tests after we developed...it needed to be done quickly.

+2  A: 

I'm making the assumption that this is in one of your controllers. Further, I'm assuming that you have a way to pass the view data in via a constructor or setter, and that you have a way to register the AuthenticateUnitAccount handler. Given that, I'd do something like the following:

[TestMethod]
public void OnAuthenticateUnitAccountSuccessTest()
{
    IAuthenticationView view = MockRepository.GenerateStub<IAuthenticationView>();
    view.Stub( v => GetPlayerID() ).Returns( 1 );
    view.Stub( v => GetSecurityCode() ).Returns( 2 );

    FakeAuthenticator authenticator = MockRepository.GenerateMock<FakeAuthenticator>();
    authenticator.Expect( a => a.Authenticate( 1, 2 ) );

    Controller controller = new Controller( view );
    controller.AuthenticateUnitAccount += authenticator.Authenticate;

    controller.OnAuthenicateAccount()

    authenticator.VerifyAllExpectations();
}

The FakeAuthenticator class contains an Authenticate method that matches the signature of your handler. Because you need to know if this method is called, you need to mock it rather than stub it to make sure it is called with the proper arguments, etc. You'll notice that I'm directly invoking the method rather than raising an event. Since you only need to test your code here, there's no need to test what happens when the event is raised. You may want to test that elsewhere. Here we just want to know that the proper methods get called with the right arguments.

For failure you could do something like:

[TestMethod]
[ExpectedException(typeof(UnauthorizedException))]
public void OnAuthenticateUnitAccountFailureTest()
{
    IAuthenticationView view = MockRepository.GenerateStub<IAuthenticationView>();
    view.Stub( v => GetPlayerID() ).Returns( 1 );
    view.Stub( v => GetSecurityCode() ).Returns( 2 );

    FakeAuthenticator authenticator = MockRepository.GenerateMock<FakeAuthenticator>();
    authenticator.Expect( a => a.Authenticate( 1, 2 ) )
                 .Throw( new UnauthorizedException() );

    Controller controller = new Controller( view );
    controller.AuthenticateUnitAccount += authenticator.Authenticate;

    controller.OnAuthenicateAccount()

    authenticator.VerifyAllExpectations();
}
tvanfosson
No, it isn't in the controller. It's in the presenter actually. You are correct that the presenter gets the view assigned in the constructor. All that method is doing is calling an event that the controller is listening to. But your example definitely helps.
nportelli