When executing the second line of this code Rhino Mocks throws an InvalidOperationException with a message "This action is invalid when the mock object is in replay state"
var mockScanner = MockRepository.GenerateMock<PortScanner>(null);
mockScanner.Expect((scanner => { scanner.Scan(null, null); }));
Stepping through the code in a debugger one can see the debugger run the method defined in the class and directly after control leaves this method the exception occurs.
This similar code in another test does work without issue
var mockView = MockRepository.GenerateMock<IScanView>(null);
mockView.Expect(view => { view.Close(); });
var controller = new ScanController(mockView);
controller.Exit();
mockView.VerifyAllExpectations();
The only difference that I can think of that might be of any consequense between theese two tests is that Exit is a member on an interface while Scan is a virtual member on a class
What am I missing?
Update
Further exploration has indicated that this is related to the way Rhino handles virtual methods. I am focusing mmy study of the documentation here now
What happens when you mock something? First of all, we should define what a mock is: In a unit test, mock objects can simulate the behavior of complex, real objects and are therefore useful when it is impractical or impossible to incorporate a real object into a unit test. Mocking makes sense in a unit testing context.
Benefits of EasyMock No Handwriting − No need to write mock objects on your own. Refactoring Safe − Renaming interface method names or reordering parameters will not break the test code as Mocks are created at runtime. Return value support − Supports return values. Exception support − Supports exceptions.
The exception was caused because Rhino Mocks did not have the required level of access to the type in order to mock it properly. Granting internal access to the Rhino Mocks assembly using InternalsVisibleTo solved the problem.
It's noteworthy that this does not affect interfaces. I believe the reason for this is because the mocking framework needs to override the implementation on a class where there is none on an interface.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With