Okay, my previous post, I said that nMock2 was better - I changed my mind.
It was just that I didn't know how to use the damn tool. But having used Rhino Mocks for over 8+ months now It has become my favorite mocking tool...
To show you guys some nyahh, check this passive view mvp test using rhino:
[Test]
public void Load_ShouldLoadView()
{
MockRepository mockery = new MockRepository();
IPimpBlogView view = mockery.CreateMock<IPimpBlogView>();
IBlogPostTask task = mockery.CreateMock<IBlogPostTask>();
view.Load += null;
IEventRaiser raiser = LastCall.Constraints(Is.NotNull()).GetEventRaiser();
Expect.Call(task.GetBlogPosts()).Return(new List<IBlogPost>());
view.BlogPosts = new List<IBlogPost>();
LastCall.IgnoreArguments();
mockery.ReplayAll();
new PimpBlogPresenter(view, task);
raiser.Raise(null, null);
mockery.VerifyAll();
}
As you can see from the above test, that is f'in pimp... I used an event raiser to raise my "Load" method to pretend it did stuff to load all my blog posts...
Below is the code for the passive mvp for those who missed out on the "pink" of enterprise development last year:
public class PimpBlogPresenter
{
private readonly IBlogPostTask task;
public PimpBlogPresenter(IPimpBlogView view, IBlogPostTask task)
{
this.task = task;
view.Load += delegate { HookUpEventsFor(view); };
}
public PimpBlogPresenter(IPimpBlogView view) : this(view, new BlogPostTask())
{
}
private void HookUpEventsFor(IPimpBlogView view)
{
view.BlogPosts = task.GetBlogPosts();
}
}
The Form & View
public partial class PimpBlog : Page, IPimpBlogView
{
#region IPimpBlogView Members
public IEnumerable<IBlogPost> BlogPosts
{
set
{
blogPostRepeater.DataSource = value;
blogPostRepeater.DataBind();
}
}
#endregion
protected override void OnInit(EventArgs e)
{
new PimpBlogPresenter(this);
base.OnInit(e);
}
}
public interface IPimpBlogView
{
IEnumerable<IBlogPost> BlogPosts { set; }
event EventHandler Load;
}
In conclusion, Rhino Mocks is pimp. Thanks Ayende for making such an awesome weapon for dealing with the pain!

10 comments:
Why wouldn't a ho herder like you use the following syntax instead of ReplayAll() and VerifyAll()?
using (mockery.Record())
{
...
}
using (mockery.Playback())
{
...
}
Yo Don,
As a simple ho herder, i'm still stuck with my old habbits... But thanks for reminding me about the pimper version!
Do you find that: LastCall.IgnoreArguments();
Sucks!
Create a list, then return that instance, then load it into your view. That will remove the ignore.
Also, get rid of the two constructors in the presenter. Use a lazy setter for the task.
Hey GutZofter,
I don't mind LastCall.IgnoreArguements(); It seems to do the trick.
Also in regards to getting rid of the multiple constructors, and using a lazy constructor is not my style... I prefer the constructor dependency injection...I don't like how you HAVE to know that you HAVE to set a property to mock it out... might as well let my constructor do it... I can get rid of 1 constructor via IoC.
Re - "and using a lazy constructor is not my style..."
It should be:
"and using a lazy setter is not my style"
I'm not trying to be critical. I'm trying to figure out ASPX portion of the view. OK?
In your code page you use this:
new PimpBlogPresenter(this);
why not this:
new PimpBlogPresenter(this, new BlogPostTask());
Now you can get rid of the constructor overload. The only reason is you don't want the view to have a reference to the BlogPosttask?
Thanks for the comments GutZofter... but here is my arguement with
new PimpBlogPresenter(this, new BlogPostTask());
"The only reason is you don't want the view to have a reference to the BlogPosttask?" - yes.
Why does the UI need to know of the service (task) layer? All the UI needs to know is to talk to a presenter... SRP.
In my actual applications, i only have the 1 constructor that initializes my service (task) object through Inversion of Control.. I use windsor...
Soo my presenter usually looks like this
public PimpBlogPostPresenter()
{
this.task = DependencyResolver.GetImplementationOf<IBlogPostTask>();
}
the DependencyResolver object is the container that has the concrete or even mocked implementation of my task layer.
Again this is just coding style... definately no right/wrong answers here...
by the way, have I met you before? Are you from edmonton?
Windsor? K! I'll looking into having a service inject dependencies.
And no not from Edmonton. I'm in SoCal. But have visited the eastern provinces. Nova Scotia, Toronto, Quebec, Montreal, and Ottowa. I use to live in New Hampshire for a few years before returning to home in Ca.
Ya it's windsor container by castle projects... frikken awesome! it's like spring.net.
Definately check it out.. and once you get the hang of ghetto xml configuration of windsor, try out binsor by Ayende (the rhino mocks guy)
binsor is the boo implementation of windsor container config file, so wayyy shorter than coding the xml for windsor container
Post a Comment