RhinoMocks and Constrained Expectations
RhinoMocks lets you define precise expectations using constraints like `Matches()`. Learn how to use predicates and method calls for powerful, targeted mocking.
Here are some tests to illustrate how to leverage RhinoMocks constraints. Notice that it is easier to get a passing test on failing code with a stub.
With the Matches() method, you can use any predicate or method call that returns a boolean. You cannot, however, use a lambda with a method body (e.g., () => {}). That will not compile.
[TestClass]
public class Tests
{
[TestMethod]
public void Should_Allow_Constraint()
{
// Arrange
var mock = MockRepository.GenerateStrictMock<ITestExerciser>();
mock.Expect(x => x.DoSomething(Arg<List<ITest>>.Matches(c => c.First() is Test)))
.Return("TestPass");
var tester = new Tester(mock);
// Act
var result = tester.DoIt();
// Assert
mock.VerifyAllExpectations();
Assert.AreEqual("TestPass", result);
}
[TestMethod]
public void Should_Enforce_Constraint_On_Strict_Mock()
{
// Arrange
var mock = MockRepository.GenerateStrictMock<ITestExerciser>();
mock.Expect(x => x.DoSomething(Arg<List<ITest>>.Matches(c => c.Any(t => t is Test))))
.Return("TestPass");
var tester = new Tester(mock);
// Act
var result = tester.DoItWrong();
// Assert
mock.VerifyAllExpectations();
Assert.AreEqual("TestPass", result);
}
[TestMethod]
public void Should_Allow_Manual_Enforce_Constraint_On_Stub()
{
// Arrange
var mock = MockRepository.GenerateStub<ITestExerciser>();
mock.Expect(x => x.DoSomething(Arg<List<ITest>>.Matches(c => TestSomething(c))))
.Return("TestPass");
var tester = new Tester(mock);
// Act
var result = tester.DoItWrong();
// Assert
mock.AssertWasCalled(x => x.DoSomething(Arg<List<ITest>>.Matches(c => c.Any(t => t is Test))));
Assert.AreEqual("TestPass", result);
}
private bool TestSomething(List<ITest> tests)
{
return true;
}
}
public class Tester
{
private ITestExerciser _testExerciser;
public Tester(ITestExerciser testExerciser)
{
_testExerciser = testExerciser;
}
public object DoIt()
{
return _testExerciser.DoSomething(new List<ITest>() { new Test() });
}
public object DoItWrong()
{
return _testExerciser.DoSomething(new List<ITest>() { new TestBase() });
}
}
public class TestExerciser : ITestExerciser
{
public object DoSomething(List<ITest> args)
{
return null;
}
}
public interface ITestExerciser
{
object DoSomething(List<ITest> args);
}
public class Test : TestBase { }
public class TestBase : ITest
{
public int Id { get; set; }
}
public interface ITest
{
int Id { get; set; }
}