Ayende @ Rahien

Refunds available at head office

Hibernating Rhinos - Episode #1: Rhino Mocks 101

To celebrate the Rhino Mocks 3.0 release, I produced a screen cast of about an hour, talking about how you can use it. This is the very first time that I am doing something like this, so the list of fubars in this episode is fairly long. For instance, I didn't realize that the Play/Pause bar would appear in the final movie, or thought about closing the IM during recording, etc.

At any rate, I think that this could provide a gentle introuction to Rhino Mocks, and help understand how to use it. The first few minutes are introductions and power point, but from then on, it is all code, so have fun.

You can watch it here.

Oh, and happy mocking.

Comments

cristian
03/28/2007 09:42 PM by
cristian

Would you mind checking the download? It doesn't seem to work.

Adam
03/28/2007 09:46 PM by
Adam

Same for me...

Leo
03/28/2007 09:50 PM by
Leo

Wow atleast hide the detailed error page !!

Ayende Rahien
03/28/2007 10:02 PM by
Ayende Rahien

Please try now, it works.

@Leo, sorry about the error, I turned detailed errors on so I could figure out issues with the site.

Adam Tybor
03/28/2007 11:53 PM by
Adam Tybor

Very nice! I can't wait to see more.

If you continue to do these one suggestion would be to try and include, like you did with Do() and LastCall.Constraints, practical examples of how to take advantage of all magic in RhinoMocks.

As always, nice work.

Chris Vickerson
03/29/2007 12:50 AM by
Chris Vickerson

I do appologize in advance if this information is in this first webcast - I'll watch it later tonight. I've been contemplating using RhinoMocks for quite some time - to finally learn how to incorporate mocking into our process of developing. When I approach others I work with I always get hammered with reasons not to use mock objects. One that keeps coming up is how to mock frameworks such as Windows Workflow Foundation. Would you consider covering the topic of mocking large existing frameworks (eg. ASP .Net or WWF)?

ralf
03/29/2007 06:14 AM by
ralf

Your download is broken.

Exception Details: NHibernate.QueryException: in expected: f [from Feed f where f.Section.Id = :sectionId]

Ayende Rahien
03/29/2007 06:31 AM by
Ayende Rahien

@Chris,

I did some work a while ago about mocking WCF, you can search the blog on that

ASP.Net itself is not mockable/testable easily, and that is a big draw back as far as I am concerned.

I am talking about it in the screencast, but in general it is a bad thing to mock stuff that you don't controol/own.

The reason is that you usually does a lot of low granularity work with it, which is a PITA to mock.

Adapters are usually the answer for this case.

Ayende Rahien
03/29/2007 06:36 AM by
Ayende Rahien

@Ralf,

Please try now, it is working.

Joe
03/29/2007 02:43 PM by
Joe

You mention early on that you consider testing webservices / database calls to be integration testing. A lot of what I (and I would imagine pleanty of other people) do centers around getting the stored procs / views set up and ensuring that the right data is being returned, and for those of us not using any kind of OR/M, ensuring that we can do the CRUD from our applications. What would be your suggestion on how to approach this?

Liang
03/29/2007 02:56 PM by
Liang

Which tool we should use to view? I only can hear... Thanks!

Ralf
03/29/2007 04:15 PM by
Ralf

Download works like a charm, screencast is really good. Maybe the next time you should post at what time in the screencast you start coding, so I can jump just there ;-)

One thing I noticed: You always go back to the unit test code after you have changed something and have to run the test again. Are you doing that intentionally for the sake of the screencast or are you unware of Testdrivens "Repeat Test Run" command. I know it took me a couple of month until I discovered it. Know I have a keyboard shortcut for it

Ayende Rahien
03/29/2007 05:11 PM by
Ayende Rahien

@Liang,

You need to install the TSCC plugin (you can find the download link at the download page) and watch it in Windows Media Player

Doug Rohm
03/29/2007 11:58 PM by
Doug Rohm

I can't get it to download either. The links in the post go to the same page.. I also have the plugin installed so it can't be that...

Doug

Adam Tybor
03/30/2007 04:41 AM by
Adam Tybor

@Joe

Checkout Rhino Commons, it has some nice text fixture stubs in ForTesting that allows you to use SqlCe and SqlLite to do quick "integration testing".

While CRUD testing is important the ORM handles this for you. The only persistence stuff I test is ensuring things like lazy loading and cascades are being handled properly. SqlCe works perfect for that. For the heavier integration tests we let our CI server handle that. Rarely do we find that integration tests fail if all unit tests are passing.

Adam

Ayende Rahien
03/30/2007 08:06 AM by
Ayende Rahien

What do you mean, you can't download it?

The link in the post goes to the download page, and the link to actually download the link to actually download the file is in the bottom of the screen.

Gulli
03/30/2007 10:16 AM by
Gulli

The confusion is about the text "You can watch it here" where "here" is a link.

Naturally, we click "here", but that's just a link to the same page. :)

Ayende Rahien
03/30/2007 10:52 AM by
Ayende Rahien

Oh, that is just the post text, actually. sorry about being confusing

Robert Taylor
03/30/2007 03:10 PM by
Robert Taylor

I really like the video - you did an excelent job of showing how to use RhinoMocks in a (near) real-world scenario. You mentioned how it is common for developers to forget to call ReplayAll() and i think i have a solution to that problem: take advantage of the "using" statement in the language by implementing a couple of new APIs and IDisposable...

using System;

using MbUnit.Framework;

using Rhino.Mocks.Constraints;

namespace Rhino.Mocks.Demo

{

[TestFixture]

public class RhinoMocks101Fixture

{

private MockRepository mockRepository;

private ISmsSender smsSender;

private IUserRepository userRepository;

private User user;

private LoginController loginController;


[SetUp]

public void TestInitialize()

{

  mockRepository = new MockRepository();

  smsSender = mockRepository.CreateMock<ISmsSender>();

  userRepository = mockRepository.CreateMock<IUserRepository>();

  user = CreateUser();


  loginController = new LoginController(smsSender, this.userRepository);

}


[Test]

public void WillSendSMSWhenUserRequestNewPassword()

{

  //nested scopes are not allowed; exception will be thrown

  //calling any mocked API outside of a scope will throw an exception

  using (this.mockRepository.RecordScope())

  {

    Expect.Call(this.userRepository.GetById("sally")).Return(this.user);

    smsSender.SendSms(null, null);

    LastCall.Constraints(Is.Equal(this.user.Phone), Text.StartsWith("New passord:"));

  }


  using (this.mockRepository.PlaybackScope())

  {

    loginController.SendNewPassword(this.user.Name);

  } //disposing of the PlaybackScope will call VerifyAll()


  Assert.AreNotEqual("old", this.user.Password, "expected the password to change");

}

}

}

Kirill
04/03/2007 06:13 AM by
Kirill

Great screencast! Btw, what font do you use in visual studio?

Ayende Rahien
04/03/2007 10:27 AM by
Ayende Rahien

Thanks, and it is consolas.

Christopher Bennage
04/03/2007 04:01 PM by
Christopher Bennage

Ayende has published an excellent sceencast introduction to Rhino Mocks . If you are at least somewhat

Ayende Rahien
04/04/2007 04:33 AM by
Ayende Rahien

I am aware of the Repeat Test Run, but I keep forgetting about it.

It is great when I am in the code, and I can just run the test again and again until I get it right.

In fact, if I am not mistaken, this is there because of a feature requst I made.

Ayende Rahien
04/04/2007 04:35 AM by
Ayende Rahien

@Robert,

Rhino Mocks had using() scope for verification at the beginning, but it was removed because people kept running into issues with it.

The most common issue was that if an exception was thrown when the mocks was in an invalid state, the using's dispose kicked in, attempted to verify, failed, and then threw a different exception, masking the real issue.

jdn
05/14/2007 01:03 AM by
jdn

http://www.blogcoward.com/archive/2007/05/13/15.aspx

Comments have been closed on this topic.