How to clear previous setup using Rhino Mocks


Hello ;). Recently, when I wrote tests using RhinoMocks framework for mocks and stubs creation I had one case, in which I needed to stub property to return one value and then overwrite this setup to return another. In this post I will show you how to do this.

Consider this class – PaymentCalculatorFormatter which can create payment report for some employee:

public class PaymentReportFormatter { private readonly IPaymentCalculator paymentCalculator; public PaymentReportFormatter(IPaymentCalculator paymentCalculator) { this.paymentCalculator = paymentCalculator; } public string Format(Employee employee) { int calculatedPayment = paymentCalculator.Calculate(employee.Id, DateTime.Now.Year); return string.Format("Employee {0} earned {1}", employee.FirstName, calculatedPayment); } }

 

This class takes one dependency – IPaymentCalculator instance, which performs actual payments calculation. Here is code of IPaymentCalculator interface.

public interface IPaymentCalculator { int Calculate(int employeeId, int year); }

As you can remember, you can stub some property using this fluent RhinoMocks API:

paymentCalculatorMock .Stub(calculator => calculator.Calculate(1, 2012)) .Return(10000);

Now, consider this test which just prints formatted report for employee:

[TestMethod] public void CalculatePaymentTest() { paymentCalculatorMock.Stub(calculator => calculator.Calculate(1, 2012)).Return(10000); string actual = target.Format(new Employee { Id = 1, FirstName = "John"}); Debug.WriteLine(actual); }

CalculatePaymentTest : Passed

Employee John earned 10000

The next test tries to call Stub method twice to return different values for exactly same parameters:

[TestMethod] public void CalculatePaymentTestWithRestub() { paymentCalculatorMock.Stub(calculator => calculator.Calculate(1, 2012)).Return(10000); string actual = target.Format(new Employee { Id = 1, FirstName = "John" }); Debug.WriteLine(actual); paymentCalculatorMock.Stub(calculator => calculator.Calculate(1, 2012)).Return(20000); actual = target.Format(new Employee { Id = 1, FirstName = "John" }); Debug.WriteLine(actual); }

I expected, that second call to Stub method will overwrite setup of the first call, but it didn’t:

CalculatePaymentTestWithRestub : Passed

Employee John earned 10000

Employee John earned 10000

To perform actual overwrite you need to call this chain of methods:

paymentCalculatorMock .Stub(calculator => calculator.Calculate(1, 2012)) .Repeat.Any() .Return(20000);

After this line of code, you will have this output:

CalculatePaymentTestWithValidRestub : Passed

Employee John earned 10000

Employee John earned 20000

Call to Repeat property and then to Any method doesn’t tell what this code actually does, so you can create extension method which has more descriptive name:

public static class MethodOptionsExtensions { public static IMethodOptions<T> ClearPrevious<T>(this IMethodOptions<T> methodOptions) { return methodOptions.Repeat.Any(); } }

After usage of this extension method you will get more readable code:

paymentCalculatorMock .Stub(calculator => calculator.Calculate(1, 2012)) .ClearPrevious() .Return(20000);

I hope that this post will help you in case you have some confusion regarding setups of return values using RhinoMocks.

Advertisements