I am trying to test a class similar to the example below:
public class Service : IService
{
public string A(string input)
{
int attemptCount = 5;
while (attemptCount > 0)
{
try
{
return TryA(input);
}
catch (ArgumentOutOfRangeException)
{
attemptCount--;
if (attemptCount == 0)
{
throw;
}
// Attempt 5 more times
Thread.Sleep(1000);
}
}
throw new ArgumentOutOfRangeException();
}
public string TryA(string input)
{
// try actions, if fail will throw ArgumentOutOfRangeException
}
}
[TestMethod]
public void Makes_5_Attempts()
{
// Arrange
var _service = MockRepository.GeneratePartialMock<Service>();
_service.Expect(x=>x.TryA(Arg<string>.Is.Anything)).IgnoreArguments().Throw(new ArgumentOutOfRangeException());
// Act
Action act = () => _service.A("");
// Assert
// Assert TryA is attempted to be called 5 times
_service.AssertWasCalled(x => x.TryA(Arg<string>.Is.Anything), opt => opt.Repeat.Times(5));
// Assert the Exception is eventually thrown
act.ShouldThrow<ArgumentOutOfRangeException>();
}
The partial mocking doesn't seem to accept my expectation. When I run the test I receive an error about the input. When I debug, I see that the actual implementation of the method is being executed instead of the expectation.
Am I doing this test correctly? According to the documentation ( http://ayende.com/wiki/Rhino%20Mocks%20Partial%20Mocks.ashx ): "A partial mock will call the method defined on the class unless you define an expectation for that method. If you have defined an expectation, it will use the normal rules for this."
It's is important to note that mocking frameworks like Rhinomocks, Moq and NSubstitute use a feature in .NET called DynamicProxy that dynamically generates a derived class of the mock in memory. Classes must:
Methods must be part of the interface or made virtual so that alternate behaviors can be substituted at runtime.