This is NOT a question about which is the best framework, etc.
I have never used a mocking framework and I\'m a bit puzzled by the idea. How does it know how to create t
A mocking framework takes the redundancy and boilerplate out of a mocking test.
It knows to create the Mock object because you tell it to, of course (unless you meant something else with that question).
The "standard" way of creating a mock object is to use/abuse the java.lang.reflect.Proxy class to create a runtime implementation of the interface. This is done at runtime. Proxy has a limitation in that it cannot proxy concrete classes. To accomplish mocking of concrete classes requires dynamic bytecode creation that creates subclasses that override the real implementation of the public methods with essentially what would be done with a Proxy (record the method parameters and return a pre-determined value). This has a limitation in that it cannot subclass final classes. For that, you have solutions like JDave, which (I believe, I didn't confirm this) muck with the classloader to remove the final designation on the class before loading it, so the class isn't in fact final at runtime as far as the JVM is concerned.
The Mocking framework is basically all about capturing the parameters and verifying them against pre-determined expectations, and then returning a pre-configured or reasonable default value. It doesn't behave in any particular way, which is the point. The calling code is being verified that it calls the method with the correct parameter, and perhaps how it reacts to a specific return values or thrown exceptions. Any side effects or real accomplishments of the call on the real object do not happen.
Here is a real example from a project, using JMock with JUnit4. I have added comments to explain what is going on.
@RunWith(JMock.class) //The JMock Runner automatically checks that the expectations of the mock were actually run at the end of the test so that you don't have to do it with a line of code in every test.
public class SecuredPresentationMapTest {
private Mockery context = new JUnit4Mockery(); //A Mockery holds the state about all of the Mocks. The JUnit4Mockery ensures that a failed mock throws the same Error as any other JUnit failure.
@Test
public void testBasicMap() {
final IPermissionsLookup lookup = context.mock(IPermissionsLookup.class); //Creating a mock for the interface IPermissionsLookup.
context.checking(new Expectations(){{ //JMock uses some innovative but weird double brace initialization as its standard idom.
oneOf(lookup).canRead(SecuredEntity.ACCOUNTING_CONTRACT);
//expect exactly one call to the IPermissionsLookup.canRead method with the the enum of ACCOUNTING_CONTRACT as the value. Failure to call the method at all causes the test to fail.
will(returnValue(true)); //when the previous method is called correctly, return true;
}});
Map map = new SecuredPresentationMap(lookup, SecuredEntity.ACCOUNTING_CONTRACT);
//This creates the real object under test, but passes a mock lookup rather than the real implementation.
JLabel value = new JLabel();
map.put("", value);
assertThat(((JLabel) map.get("")), is(value)); //This ensures that the Map returns the value placed, which it should based on the fact that the mock returned true to the security check.
}
}
If the mock passed in was ignored, the test would have failed. If the map fails to return the value placed in it the test fails (that is standard JUnit).
What is being tested here and in another opposite test is that depending on what the IPermissionsLookup interface says about the security the Map changes its behavior about what is returned. This is the base good case. The other test, the mock returns false and something else is expected from the Map. Using the mock ensures that the map relies on the IPermissionsLookup method to determine the security posture and what is being returned.