Scripting Custom Actions
Using a custom action 1 in an expectation is straightforward but requires quite a lot of code. You need to define a class that implements the action and a factory method to make the expectation read clearly. The jMock Scripting Extension lets you define custom actions inline in the expectation, as BeanShell 2 scripts.
Because a script is represented as a string, it does not play well with refactoring tools.
First, you need to add the following JARs to your classpath:
- jmock-script-2.6.1.jar
- bsh-core-2.0b4.jar
Second, you need to import the "perform" factory method into your test.
import static org.jmock.lib.script.ScriptedAction.perform;
You can then use the "perform" factory method to define custom actions using a BeanShell script. The script can refer to the parameters of the mocked method by the names 0ドル (the first parameter), 1ドル, 2ドル, etc. For example, the script below calls back to a Runnable passed as the first (and only) parameter:
checking(new Expectations() {{ oneOf (executor).execute(with(a(Runnable.class))); will(perform("0ドル.run()")); }}
A script can pass literal values as parameters to the callback. For example, the script below adds an integer to a collection:
checking(new Expectations() {{ oneOf (collector).collect(with(a(Collection.class))); will(perform("0ドル.add(2)")); }}
If you want a script to refer to an object defined by the test, you will have to define a script variable with a "where" clause. Any number of where clauses can be appended onto the perform clause to define variables. For example, to translate the code from the custom action recipe 3 to use a BeanShell script, we must define a script variable for the list of mangoes to be added to the collection:
final FruitTree mangoTree = mock(FruitTree.class); final Mango mango1 = new Mango(); final Mango mango2 = new Mango(); context.checking(new Expectations() {{ oneOf (mangoTree).pickFruit(with(a(Collection.class))); will(perform("0ドル.addAll(mangoes)") .where("mangoes", Arrays.asList(mango1, mango2)); }}); ...