views:

700

answers:

4

So I'm new to rhino mocks and I'm trying to get it going in a MVP patterned project I'm on. So I've got an interface representing my View and a class for my Presenter like so:

public interface IView {
  string SomeData { get; set; }
}

public class Presenter {
  public IView View { get; set; }
  public void Init(IView view) {
    this.View = view;
  }

  public virtual string DoStuff(){
    return "Done stuff with " + this.View.SomeData;
  }
}

And I'm trying to set up a test to mock the DoStuff method, so I've got a basic fixture like this:

[TestMethod]
public void Test(){
  var mocks = new MockRepository();
  var view = mocks.Stub<IView>();
  var presenter = mocks.StrictMock<Presenter>();

  presenter.Init(view);

  using(mocks.Record()){
    presenter.Expect(p => p.DoStuff()).Return("Mocked result");
  }

  string result = string.Empty;
  using(mocks.Playback()){
    result = presenter.DoStuff();
  }

  Assert.AreEqual(result, "Mocked result");
}

But I keep getting a null reference exception from within the DoStuff method (during the expectation setup), because the View object is null. And this is where I'm stuck. I've called the Init method, which assigns the value of the View property, and I thought that the point of an expectation setup was that the method itself wasn't ever called?

+2  A: 

You need to mock the View property as well, instead of calling the Init method on the mocked presenter.

presenter.Expect( p => p.View ).Return( view );

You might also want to look at using the new AAA (Arrange-Act-Assert) syntax for RhinoMocks.

string expectedResult = "Done stuff with Mocked Result";

var view = MockRepository.GenerateMock<IView>();
view.Expect( v => v.SomeData ).Return( "Mocked Result" );

var presenter = new Presenter();
presenter.Init( view );

string actualResult = presenter.DoStuff();

Assert.AreEqual( expectedResult, actualResult );

view.VerifyAllExpectations();

EDIT After looking at this again, I would agree with @ayende that you should probably only mock/stub the view not the presenter. I'll leave the original correction to get your code to work, but update my example to reflect the latter.

tvanfosson
What are you testing?
Gutzofter
He's testing that the View property is called and the DoStuff() method is also called. It's just some demo code to see how AAA syntax looks.
sirrocco
I'll update with assert for value...
tvanfosson
A: 

From what I see of your source code and your tests it is hard to see what your actually trying to test. The View? The Presenter?

Since you have an interface for your view and a class implementation for your presenter, I think you want to mock the view and test the presenter.

Here is the group site (I posted a link to this question on it for you):

http://groups.google.com/group/RhinoMocks

See this code. It is from 2007, but it can get you the gist of mocking.

http://tech.groups.yahoo.com/group/AgileEmbedded/files/HomeGuard/

Gutzofter
+8  A: 

It looks like you are testing Rhino Mocks. You are mocking both the view and the presenter. I am going to assume that mocking the presenter is not desireable, and you should mock only the view.

A: 

As others have written, you need to decide what code you are trying to test and only mock the other stuff. If you are trying to test the presenter, then you only want to mock/stub out the view while still using a real presenter. Something like this:

[TestMethod]
public void Test(){
  var view = MockRepository.GenerateStub<IView>();
  var presenter = new Presenter();
  presenter.Init(view);
  view.SomeData = "Test";
  Assert.AreEqual(presenter.DoStuff(), "Done stuff with Test");
}

You are then testing that the Presenter.DoStuff() method correctly uses the view.

Hope this helps.

David Tchepak