Reputation: 11
I'm new to JMockit and writing a test for a quite complex class, call it XYZ. In each @Test method, I want to call the corresponding real method of XYZ, but mock all (or sometimes nearly all) other methods, which should by verified afterwards. At the moment my first test method looks like this (I want to mock all methods except "start", so I'm using a regex):
@Test
public void testStart(@Mocked({ "^(start).*" }) XYZ xyz) {
new Expectations() {{
xyz.isValidState(); result = true;
}};
...
}
When I run the test, I get "java.lang.IllegalStateException: Missing invocation to mocked type at this point; please make sure such invocations appear only after the declaration of a suitable mock field or parameter" (at the line where the first expectation is defined) which seems to say that the mocking did not work. Is my regex wrong or this there another problem?
Upvotes: 1
Views: 4533
Reputation: 16380
That regex selects the methods that will be mocked. So, isValidState()
does not get mocked, as it doesn't match the expression; hence JMockit says there was no mocked invocation at the point the "result" field is used.
There is no way to not mock just a single method in a class while mocking all others, except for using partial mocking with new Expectations(XYZ.class)
and then recording expectations on all the methods that should be mocked. This, of course, would be cumbersome. Which is a good thing here, because partial mocking in general is not a feature to be used in "normal" cases; it's only for exceptional situations.
If you want to unit test a class, even a complex one, mocking should be restricted to its dependencies, and even then only those dependencies that you choose or need to regard as external to the unit under test. That said, if a given internally called method in XYZ
gets in the way of a clean test, then you can exceptionally choose to "mock it out" through partial mocking; but that would usually mean a single method (or just a few) in class XYZ
to be mocked per test.
Upvotes: 3