Ayende @ Rahien

Refunds available at head office

Planning for Rhino Mocks 4.0

Well, now that Rhino Mocks 3.6 is out of the way, we need to think about what the next version will look like.

Initially, I thought to match Rhino Mocks 4.0 to the .NET 4.0 release and support mocking dynamic variables, but while this is still on the planning board, I think that it is much more important to stop and take a look at where Rhino Mocks is now and where we would like it to be.

I started Rhino Mocks about 5 years ago, and the codebase has stood well in the test of time. There aren’t any nasty places and we can keep releasing new features with no major issues.

However, 5 years ago the community perception of mocking was different than what it is now. Rhino Mocks hasn’t really changed significantly since it 1.1 days, for that matter, you can take a code base using Rhino Mocks for .Net 1.1 and move it to Rhino Mocks 3.6 with no issues.

But one of the most frequent complaints that I have heard is that Rhino Mocks API has became too complex over the years, there are too many options and knobs that you can turn. I know that my own style of interaction testing has changed as well.

The current plan for Rhino Mocks 4.0 is that we will break backward compatibility in a big way. That means that we are going to drastically simplify everything in the framework.

We are still discussing this in the mailing list, but currently it looks like we will go with the following route:

  • Kill the dynamic, strict, partial and stub terminology. No one cares. It is a fake.
  • Remove the record / playback API. The AAA method is much simpler.
  • Simplify mocking options, aiming at moving as much as possible from expectation style to assert style.
  • Keep as much of the current capabilities as we can. That means that if Rhino Mocks was able to support a scenario, it should still support it for the 4.0 version, hopefully in a simpler fashion.

The end result is putting Rhino Mocks on an API diet. I am looking for help in doing this, both in terms of suggested syntax and in terms of actual patches.

You are welcome to contribute…

Comments

Dmitry
09/03/2009 04:47 PM by
Dmitry

Sounds great.

Dave The Ninja
09/03/2009 05:20 PM by
Dave The Ninja

If I can assist in any way please let me know oren.

Davie

Diego Mijelshon
09/03/2009 06:11 PM by
Diego Mijelshon

The design decisions seem 100% correct and aligned with the way people think about mocks these days.

It'll be a lot more like Moq, though :-)

Noel Kennedy
09/03/2009 06:12 PM by
Noel Kennedy

Completely agree with the strategy.

How about including simple automocking 'container'? I don't really like the term 'container', but that's what the concept appears to be called atm!

I have one which instantiates the sut by injecting fakes into the ctor. You then ask the container to return the stubs you want to set expectations on. Mine works a bit like this:

var sut = mocks.MakeSut <myconcretesut;

var fake = mocks.GetFake <imyfakethatgotinjected();

fake.Expect(etcetc);

Radenko Zec
09/03/2009 06:20 PM by
Radenko Zec

Great plans. Sound good.

Chris Brandsma
09/03/2009 06:39 PM by
Chris Brandsma

I'm with everyone else here. I love the idea of simplifying the api down.

Bryan
09/03/2009 06:39 PM by
Bryan

I suggest you put it in a different namespace and assembly. That way, we can easily have 3.6 and 4.0 live side by side in one test project. We can start using 4.0 for all new tests, and let old tests that still use 3.6 but are still valid rot.

Ayende Rahien
09/03/2009 06:42 PM by
Ayende Rahien

Dave,

I would be delighted, we are having a conversation about that in the mailing list, you are welcome to join in

John Chapman
09/03/2009 06:48 PM by
John Chapman

Ayende,

I completely agree that's the right move for the framework. Whenever I give a talk on Rhino Mocks I pretty much state to ignore all of the different terms, but offer to explain them afterwards if they are really curious. It has probably been the biggest confusion point with Rhino Mocks.

I worry a little bit about completely abandoning the old concepts though. I wonder if it makes sense to create a deprecated repository class which exists for one release to make it easier for people who may have used those old concepts to migrate to the new versions.

But really 3.6 works great, and people can keep using 3.6 forever, so don't upgrade unless you're prepared to rework your tests.

Barry Dahlberg
09/03/2009 09:33 PM by
Barry Dahlberg

Excellent. What you described is probably the only thing I'd ask for anyway.

Erik
09/03/2009 09:40 PM by
Erik

Could you define "AAA"?

Wes McClure
09/03/2009 10:13 PM by
Wes McClure

Simplicity rocks! I already am a huge fan of the current AAA syntax in Rhino Mocks.

Jason
09/03/2009 10:28 PM by
Jason

I agree with this plan, I would appreciate a cleanup of the older stuff since I only use the AAA style.

I also think this will lower the barrier to entry for developers that are new to mocking. Today when I hand new dev Rhino Mocks they get confused by the large API and I have to explain the history of the record/playback to the AAA.

Keep up the great work Oren, we really apreciate it!

Mark
09/03/2009 11:28 PM by
Mark

Sounds like a good idea to me. I feel RM does suffer a bit from having too many things; finding the 'best' way to do things turned up a lot of options to filter through. I'll definitely give a thumbs-up to a clean break.

Furthermore, I also agree with killing the strict mock / mock / stub / partial terminology. In my experience, it complicates things a lot and tends to make the learning curve a lot steeper.

Dmitriy Nagirnyak
09/03/2009 11:36 PM by
Dmitriy Nagirnyak

Just my 2 cents.

The API of RhinoMocks is actually one of the reasons I decided to use Moq.

It was a bit complex to get started with. Moq provides intuitive and IntelliSense-ish way of doing things.

I think it would be good idea to embrace Moq-like syntax with lambdas and the new .NET 4 features to simplify the API.

One of the aims could be to "write less and do more".

Isaac
09/04/2009 12:27 AM by
Isaac

The main thing you want to do is to simplify the API and make some improved docs for the common how-tos.

The API is confusing to a newcomer because there are several ways of achieving the same thing - beginners want to know that there is one way of doing something and that what they are doing is right.

Also - if you could make a way of "overriding" a stubbed method later on, that would be great. I often put a default stub in my TestInit method and then "override" it later on in specific tests, but it's difficult to do that with Rhino at the moment.

Ray
09/04/2009 12:45 AM by
Ray

I completely support those plans. I've never fully grasped why anyone would prefer the playback stuff over AAA anyways, AAA is so much more intuitive.

Noam Gal
09/04/2009 06:01 AM by
Noam Gal

Sounds great.

As a beginner with Rhino and mocking in general, I struggled with all the different ways I can use it.

Glad I managed to do AAA, as it will be the option that stays around.

Arnis L.
09/04/2009 06:50 AM by
Arnis L.

That's a right direction. In fact - i chose Moq just because of this - it's much more easier (it's API) for beginners.

cowgaR
09/04/2009 12:24 PM by
cowgaR

ok so can you confirm it'll be C# 4.0 project only?

thank you, sounds great, but .NET 4.0 is still far away (both in release and to production)

David
09/04/2009 01:02 PM by
David

A LINQ provider to RM ala Moq ( www.clariusconsulting.net/.../164978.aspx) would be nice. If RM is being put on an API diet, this is something that should probably be considered.

My main gripe is the same as Isaac's: the inability to override stubs later on in the test, and that stubs automatically use PropertyBehavior (which forces me to use DynamicMock when I need to fake read only properties). I assume the flattening of all the different mock types will be addressing issues like this.

Ayende Rahien
09/04/2009 01:57 PM by
Ayende Rahien

Davy,

I don't really like the linq syntax for Moq.

As for the other stuff, please join the mailing list, we are discussing it over there right now.

Ayende Rahien
09/04/2009 01:58 PM by
Ayende Rahien

cowgaR,

No, it will NOT be a 4.0 only version

Judah
09/04/2009 04:16 PM by
Judah

Wow, getting rid of the record/playback APIs, eh?

We've got several thousand unit test in our production project right now that use this syntax:

using(mocks.Record())

{

...

}

using(mocks.Playback())

{

...

}

Will we have to rewrite all of these to use the other syntax?

Ayende Rahien
09/05/2009 10:26 AM by
Ayende Rahien

Judah,

No, we intend to support side by side execution

Michael Braude
09/08/2009 05:37 PM by
Michael Braude

I don't think you should remove the record / playback syntax at all. There's nothing wrong with having two systems if you need to: one that's built around AAA and another that validates order.

It may be fashionable not to care about order validation, but at its heart, this is what I consider the core functionality of a mock API. It's critical that you allow users to be able to assert that one method on one object was invoked before another and that your infrastructure supports this. Whether they choose to write their tests in this style is up to them, but there are perfectly valid cases where asserting this behavior is important.

Colin Jack
09/15/2009 07:09 PM by
Colin Jack

Sounds like a great idea.

Julius Ganns
09/17/2009 04:54 AM by
Julius Ganns

Hi Ayende,

if you're looking for a fresh perspective (meaning, although I have developed some fairly complex apps and libs, I'm kind of new to Mocking and Stubbing), I would be interested in knowing how supporting your project would look like and how the API redesign is going to be planned, designed, constructed, tested and managed. Maybe you could create a new mailing list for newcomers that want to support the new 4.0 release. In that case, add my address to the list.

Best,

Julius

gkdm
10/08/2009 02:11 AM by
gkdm

Ayenda my man, Questiion about the next version of RhinoMocks,

Why not listen to the profiling API like TypeMock? seems to be a mighty mechanism..

Ayende Rahien
10/08/2009 05:50 AM by
Ayende Rahien

gkdm,

Send me a pach for hat

Comments have been closed on this topic.