Oren Eini

CEO of RavenDB

a NoSQL Open Source Document Database

Get in touch with me:

oren@ravendb.net +972 52-548-6969

Posts: 7,602
|
Comments: 51,232
Privacy Policy · Terms
filter by tags archive
time to read 2 min | 329 words

imageI have been waiting on the release for Rhino Mocks 3.5, seeing what kind of feedback I can get from users. I also had another reason, I hadn't had the chance to really give it a good testing, in the only manner that matter, using it to develop production ready software.

Here is my latest test, which I am fairly pleased with.

[TestFixture]
public class WebcastControllerTest
{ 
	private WebcastController controller;
	private IRepository<Webcast> repositoryStub;
	private StubEngineContext engineContext;
	private IUnitOfWork unitOfWorkStub;
	private IDisposable disposeGlobalUnitOfWorkRegistration;

	[SetUp]
	public void Setup()
	{
		repositoryStub = MockRepository.GenerateStub<IRepository<Webcast>>();
		unitOfWorkStub = MockRepository.GenerateStub<IUnitOfWork>();
		controller = new WebcastController(repositoryStub)
		             	{
		             		ControllerContext = new ControllerContext{Name = "webcast"},
		             	};
		engineContext = new StubEngineContext();
		controller.SetEngineContext(engineContext);
		disposeGlobalUnitOfWorkRegistration = UnitOfWork.RegisterGlobalUnitOfWork(unitOfWorkStub);
	}

	[TearDown]
	public void TearDown()
	{
		disposeGlobalUnitOfWorkRegistration.Dispose();
	}

	[Test]
	public void When_index_called_will_send_existing_webcasts_to_view()
	{
		var webcasts = new List<Webcast>();
		repositoryStub.Stub(x => x.FindAll()).Return(webcasts);

		controller.Index();

		Assert.AreSame(webcasts, controller.PropertyBag["webcasts"]);
	}

	[Test]
	public void When_display_called_will_send_webcast_to_view()
	{
		var webcast = new Webcast();
		controller.Display(webcast);

		Assert.AreSame(webcast, controller.PropertyBag["webcast"]);
	}

	[Test]
	public void When_edit_called_with_webcast_will_send_webcast_to_view()
	{
		var webcast = new Webcast();
		controller.Edit(webcast);

		Assert.AreSame(webcast, controller.PropertyBag["webcast"]);
	}

	[Test]
	public void When_saving_invalid_webcast_will_redirect_to_edit()
	{
		var webcast = new Webcast();

		controller.Validator.IsValid(webcast);
		controller.PopulateValidatorErrorSummary(webcast, controller.Validator.GetErrorSummary(webcast));

		controller.Save(webcast);

		Assert.Contains(engineContext.MockResponse.RedirectedTo, "edit");
	}

	[Test]
	public void When_saving_invalid_webcast_will_flash_error_summary_and_webcast_in_flash()
	{
		var webcast = new Webcast();

		controller.Validator.IsValid(webcast);
		controller.PopulateValidatorErrorSummary(webcast, controller.Validator.GetErrorSummary(webcast));

		controller.Save(webcast);

		Assert.AreSame(webcast, controller.Flash["webcast"]);
		Assert.AreSame(controller.Validator.GetErrorSummary(webcast), controller.Flash["errorSummary"]);
	}

	[Test]
	public void When_saving_valid_webcast_will_redirect_to_display()
	{
		var webcast = new Webcast();

		// explicitly not calling validation, the controller will assume 
		// that this is a valid object

		controller.Save(webcast);

		Assert.Contains(engineContext.MockResponse.RedirectedTo, "display");
	}

	[Test]
	public void When_saving_valid_webcast_will_save_and_flash_unit_of_work()
	{
		var webcast = new Webcast();

		// explicitly not calling validation, the controller will assume 
		// that this is a valid object

		controller.Save(webcast);

		repositoryStub.AssertWasCalled(x=>x.Save(webcast));
		unitOfWorkStub.AssertWasCalled(x=>x.TransactionalFlush());
	}
}
time to read 1 min | 132 words

Or, as I like to call them, yes another stupid language limitation. I did some work today on Rhino Mocks, and after being immersed for so long in DSL land, I had a rude awakening when I remembered just how much inflexible the C# language is.

Case in point, I have the following interface:

public interface IDuckPond
{
	Duck GetDuckById(int id);
	Duck GetDuckByNameAndQuack(string name, Quack q);
}

I want to get to a situation where the following will compile successfully:

IDuckPond pond = null;
pond.Stub( x => x.GetDuckById );
pond.Stub( x => x.GetDuckByNameAndQuack );

Any ideas?

Note that unlike my other challenges, I have no idea if this is possible. I am posting this after I got fed up with the limitations of the language.

time to read 1 min | 117 words

For various reasons which will be made clear soon, I needed to write the same test twice, once using Rhino Mocks, the second time using hand rolled stubs. I thought it was an interesting exercise, since this is not demo level code.

[Test]
public void WillCallHandlesWithWithRouteTestHanlderWhenRouteCalled_UsingRhinoMocks()
{
	const IQuackFu msg = null;

	var mocks = new MockRepository();

	var routing = dslFactory.Create<RoutingBase>(@"Routing\simple.boo");

	var mockedRouting = (RoutingBase)mocks.PartialMock(routing.GetType());
	Expect.Call(() => mockedRouting.HandleWith(null, null))
		.Constraints(Is.Equal(typeof(RoutingTestHandler)), Is.Anything());

	mocks.ReplayAll();

	mockedRouting.Initialize(msg);

	mockedRouting.Route();

	mocks.VerifyAll();
}

[Test]
public void WillCallHandlesWithWithRouteTestHanlderWhenRouteCalled()
{
	const IQuackFu msg = null;

	dslFactory.Register<StubbedRoutingBase>(new StubbedRoutingDslEngine());

	var routing = dslFactory.Create<StubbedRoutingBase>(@"Routing\simple.boo");

	routing.Initialize(msg);

	routing.Route();

	Assert.AreEqual(typeof (RoutingTestHandler), routing.HandlerType);

	Assert.IsInstanceOfType(
		typeof(NewOrderMessage), 
		routing.Transformer()
		);
}
time to read 1 min | 156 words

Eli Lopian joined the discussion about Mocks, Statics and the automatic rejection some people have of Type Mock and its capabilities.

Here is the deal.

  • I don't like the idea of mocking statics.
  • Given a patch that would add this capability to Rhino Mocks *, I would apply it in a heartbeat.

Hm... that seems inconsistent of me...

Leaving aside the fact that I feel no urging need to be internally consistent, I don't have an issue with the feature itself. Mocking statics is not inherently bad. What I consider bad is the reliance of such a feature to write highly coupled code.

It is more an issue of guidance and form than a matter of actual features.

* Note that I said, "given a patch", the feature is not actually interesting enough for me to spend time implementing it.

time to read 2 min | 243 words

3 Months ago I released Rhino Mocks 3.4, we have made some great improvement to Rhino Mocks in the meantime, and it is time for a new release. I generally don't believe in beta releases for Rhino Mocks, but this time we are coming up with a new syntax, and I want to get additional external input before we make a final release on that.

The biggest new feature is the new AAA syntax, which you can read about in the relevant post, but we had a few other new things as well.

  • CreateMock() is deprecated and marked with the [Obsolete] attribute. Use StrictMock() instead.
  • Better handling of exception in raising events from mock objects
  • Fixing an issue with mock objects that expose methods with output parameter of type System.IntPtr.
  • Allowing to return to record mode without losing expectations, thanks to Jordan Terrel, for submitting this patch.

I intend to write a lot more documentation about the new AAA syntax, but for now, you can visit the tests for the feature, to see how it works.

As usual, you can find the bits here.

Note that this release if for .Net 3.5 only. Rhino Mocks 3.5 RTM will be for .Net 2.0 and 3.5, but I am focusing on the capabilities that I can get from the 3.5 platform at the moment.

time to read 3 min | 432 words

I intend to release the new version of Rhino Mocks soon, and I wanted to show the new syntax that I have been working on. I still need to write more thorough documentation, but I think that just the syntax should be a pretty good indication of how things are going.

Without further ado, here is the code:

[Test]
public void WhenUserForgetPasswordWillSendNotification_WithConstraints()
{
    var userRepository = MockRepository.GenerateStub<IUserRepository>();
    var notificationSender = MockRepository.GenerateStub<INotificationSender>();

    userRepository.Stub(x => x.GetUserById(5)).Return(new User { Id = 5, Name = "ayende" });

    new LoginController(userRepository, notificationSender).ForgotMyPassword(5);

    notificationSender.AssertWasCalled(x => x.Send(null),
        options => options.Constraints(Text.StartsWith("Changed")));
}

[Test]
public void WhenUserForgetPasswordWillSendNotification_WithArgMatchingInTheLambda()
{
    var userRepository = MockRepository.GenerateStub<IUserRepository>();
    var notificationSender = MockRepository.GenerateStub<INotificationSender>();

    userRepository.Stub(x => x.GetUserById(5)).Return(new User { Id = 5, Name = "ayende" });

    new LoginController(userRepository, notificationSender).ForgotMyPassword(5);

    notificationSender.AssertWasCalled(x => x.Send(Arg<string>.Matches(s => s.StartsWith("Changed"))));
}

[Test]
public void WhenUserForgetPasswordWillSendNotification_WithArgumentMatching()
{
    var userRepository = MockRepository.GenerateStub<IUserRepository>();
    var notificationSender = MockRepository.GenerateStub<INotificationSender>();

    userRepository.Stub(x => x.GetUserById(5)).Return(new User { Id = 5, Name = "ayende" });

    new LoginController(userRepository, notificationSender).ForgotMyPassword(5);

    notificationSender.AssertWasCalled(x => x.Send("Changed password for ayende"));
}


[Test]
public void WhenUserForgetPasswordWillSendNotification_UsingExpect()
{
    var userRepository = MockRepository.GenerateStub<IUserRepository>();
    var notificationSender = MockRepository.GenerateMock<INotificationSender>();

    userRepository.Stub(x => x.GetUserById(5)).Return(new User { Id = 5, Name = "ayende" });
    notificationSender.Expect(x => x.Send(null)).Constraints(Text.StartsWith("Changed"));

    new LoginController(userRepository, notificationSender).ForgotMyPassword(5);

    notificationSender.VerifyAllExpectations();
}

The class under test is:

public class LoginController
{
    private readonly IUserRepository repository;
    private readonly INotificationSender sender;

    public LoginController(IUserRepository repository, INotificationSender sender)
    {
        this.repository = repository;
        this.sender = sender;
    }

    public void ForgotMyPassword(int userId)
    {
        User user = repository.GetUserById(userId);
        sender.Send("Changed password for " + user.Name);
    }
}
time to read 2 min | 202 words

Here is something that most people just don't think about, but it hits some people at the high end. Rhino Mocks is extremely efficient mocking framework, for just about any scenario. However, when it comes the time to mock large amount of interfaces (where large is in the hundreds to thousands), or if you have large interfaces (with dozens or hundreds of methods), it is costly to create the mocks. Rhino Mocks does some caching internally, but it is noticeable issue to some people.

We are talking about an extra second or two for even most pathological cases here, so in general it wouldn't warrant anything special from the library, except that there is a twist to that. Under the debugger, the amount of time spent actually generating the mock can go up by several orders of magnitudes. To add insult to injury, Visual Studio 2005 has several bugs in the debugger that will cause it to crush & burn under several such scenarios.

Karl Lew has been kind enough to not only provide a patch for Rhino Mocks to help this problem, but also document it.

Thanks, and sorry for taking so long to get to it.

On API Design

time to read 2 min | 218 words

Krzysztof points out that Rhino Mocks has 26(!) methods to create various mocks.

I was very surprised to hear that, so I took a look, and he is right. The problem is how you think about those. Those 26 methods are only applicable when you count each overload as a separate method. Without counting the overloads, we have 10 methods. Then we have to consider options. In Rhino Mocks, you tend to have the following options: Create mock, create mock with remoting, create mock from multiple types.

That works to reduce the amount of options that we have down to about 4 different types of mocks that Rhino Mocks can generate. And you know what. Almost all the time, you don't need to use them. You only have to use DynamicMock and that is it.

Krzysztof suggestion would consolidate all the options to a far smaller surface area, but it would have several major issues:

  • Break backward compatibility - I am wiling to do that, but not without due consideration.
  • Break the documentation - See previous point.
  • Force the user to deal with all the options explicitly - "In your face!" API design, from my perspective. That would lead people to create utility methods over it, which gets us right back to all the method options.

time to read 1 min | 158 words

I have been thinking about this for a while now, and I am getting ready to release Rhino Mocks 3.5. The major feature is taking advantage on C# 3.0 language features. This allow some really interesting experimentation.

var mockedSmsSender = mocks.ToBeNamedMocked<ISmsSender>();
var mockedRepository = mocks.ToBeNamedMocked<IUserRepository>();
mockedRepository.Stub( x=> x.GetUserByName("ayende") ).Return( new User{Name="ayende", Pass="1234"});

new LoginController(mockedSmsSender, mockedRepository ).ForgotYourPassword("ayende");

mockedSmsSender.Verify( x => x.Send("ayende, your pass is 1234");

A few things to note about this code.

  • No explicit record / replay model
  • Arrange Act Assert model
  • You can setup return values by using Stub()
  • You can setup expectations using Expect(), with the same syntax
  • More complex verification is also possible.
  • I don't know what to call this new mode

As an aside, I am deprecating CreateMock in favor of StrictMock. Using strict mocks by default was a bad design decision on my part.

Thoughts?

time to read 3 min | 482 words

Kyle has just posted about the MvcContrib.TestHelper project:

The CreateController method on my TestControllerBuilder uses Castle's DynamicProxy to create the controller. It also creates a ControllerContext using dynamic mocks from Rhino Mocks similar to the way Haackselman have already showed you and wires it up to the controller.

An interceptor is also attached to the controller to intercept calls to RenderView and RedirectToAction. (Actually, it intercepts all calls but only these two have special handling.) Calls to either method will populate an appropriate object on the builder class. In the example above, I'm using the RedirectToActionData object.

I'll leave aside the need to get to that level when you want to test brand new framework and code. I think that this is a serious flaw, but that is not the subject of this post. The use of dynamic proxy and interceptors caught my eye, because they aren't actually needed. Rhino Mocks can do it for you. Let us see how it is done right now.

public T CreateController<T>() where T : Controller
{
      ProxyGenerator generator = new ProxyGenerator(); //Castle DynamicProxy
      Controller controller = (Controller)generator.CreateClassProxy(typeof(T), new ControllerInterceptor(this));

      ControllerContext controllerContext = new ControllerContext(HttpContext, RouteData, controller);
      controller.ControllerContext = controllerContext;
     
      typeof(T).GetProperty("TempData").SetValue(controller, TempDataDictionary, null);

      return controller as T;
}

The controller interceptor can be found here. Let us take out the dynamic proxy part and use Rhino Mocks to handle it. In this case, it will look like this:

public T CreateController<T>(params object[] ctorArgs) where T : Controller
{
	Controller controller = _mocks.PartialMock<T>();
	
	var renderViewDataParams = new Type[]{typeof(string),typeof(string), typeof(object));
	typeof(Controller).GetMethod("RenderViewData", renderViewDataParams)
		.Invoke(controller, new [] { null, null, null });
	LastCall.IgnoreArguments().Repeat.Any()
		.Do( (RenderViewDataDelegate)delegate(string viewName, string masterName, object viewData)
	{
		RenderViewData = new RenderViewData
		{
			ViewName = viewName, 
			MasterName = masterName, 	
			ViewData = viewData
		};
	});
	
	typeof(Controller).GetMethod("RedirectToAction", new []{typeof(RouteValueDictionary}})
		.Invoke(controller, new []{null});
	LastCall.IgnoreArguments().Repeat.Any()
		.Do( (RedirectToActionDelegate) delegate(RouteValueDictionary route)
	{
		RedirectToActionData = new RedirectToActionData
		{
			ActionName = Convert.ToString(values.ContainsKey("action") ? values["action"] : ""),
			ControllerName = Convert.ToString(values.ContainsKey("controller") ? values["controller"] : "")
		};
	});

	_mocks.Repaly(controller);
	
	return controller;
}

A lot of the ugliness here is the need to make calls with reflection, because they aren't exposed externally. Ignoring that, it is really a trivial exercise.

Just to point out, I added this functionality to Rhino Mocks a long time ago, specifically to enable the Extract and Override scenarios. This is a technique used for legacy code testing, it should be frowned upon in most green field scenarios.

FUTURE POSTS

  1. A deep dive into RavenDB's AI Agents - 4 days from now
  2. Building an AI Agent using RavenDB - 7 days from now

There are posts all the way to Sep 12, 2025

RECENT SERIES

  1. RavenDB 7.1 (7):
    11 Jul 2025 - The Gen AI release
  2. Production postmorterm (2):
    11 Jun 2025 - The rookie server's untimely promotion
  3. Webinar (7):
    05 Jun 2025 - Think inside the database
  4. Recording (16):
    29 May 2025 - RavenDB's Upcoming Optimizations Deep Dive
  5. RavenDB News (2):
    02 May 2025 - May 2025
View all series

Syndication

Main feed ... ...
Comments feed   ... ...
}