EasyMock is available in the Maven central repository. Just add the following dependency to your pom.xml:
You can obviously use any other dependency tool compatible with the Maven repository.
easymock-4.3.jarto add to your classpath
EasyMock can be used on Android VM (Dalvik). Just add EasyMock and Dexmaker as dependencies of the apk project used to test your application. It is a good idea to exclude Cglib since Dexmaker is used instead. If you use Maven, the final required dependencies will look like this:
Our first test should check whether the removal of a non-existing document does not lead to a notification of the collaborator. Here is the test without the definition of the Mock Object:
For many tests using EasyMock, we only need a static import of methods of
To get a Mock Object, we need to
Here is a first example:
After activation in step 3,
mock is a Mock Object for the
Collaborator interface that expects no calls. This means that if we change our
ClassUnderTest to call any of the interface's methods, the Mock Object will throw an
There is a nice and shorter way to create your mocks and inject them to the tested class. Here is the example above, now using annotations:
mock is instantiated by the runner at step 1. It is then set by the runner, to the
listener field on step 2.
setUp method can be removed since all the initialization was done by the runner.
On top of that, since EasyMock 3.3, if you need to use another runner on you tests, a JUnit rule is also available to you. Both have the exact same behavior. Choosing one of the other is a matter of taste.
Finally, since EasyMock 4.1, JUnit 5 extensions are supported.
The annotation has an optional element, 'type', to refine the mock as a 'nice' mock or a 'strict' mock. Another optional annotation, 'name', allows setting of a name for the mock that will be used in the
mock() call, which will appear in expectation failure messages for example. Finally, an optional element, "fieldName", allows specifying the target field name where the mock should be injected. Mocks are injected to any field in any
@TestSubject that is of compatible type. If more than one mock can be assigned to the same field then this is considered an error. The
fieldName qualifier can be used in this scenario to disambiguate the assignments.
EasyMockSupport is a class that exist to help you keeping track of your mock. Your test cases
should extend or delegate to it. It will automatically registers all created mocks and replay, reset
or verify them in batch instead of explicitly. Here's an example:
Alternatively, you can also use
EasyMockSupport through delegation as shown below.
On a Mock Object returned by a
EasyMock.mock(), the order of method calls is not checked.
If you would like a strict Mock Object that checks the order of method calls, use
EasyMock.strictMock() to create it.
The equivalent annotation is
If an unexpected method is called on a strict Mock Object, the message of the exception will show the method
calls expected at this point followed by the first conflicting one.
verify(mock) shows all missing method calls.
On a Mock Object returned by
mock() the default behavior for all methods is to throw an
AssertionError for all unexpected method calls. If you would like a "nice" Mock Object that by default
allows all method calls and returns appropriate empty values (
niceMock() instead. The equivalent annotation is
Sometimes you may need to mock only some methods of a class and keep the normal behavior of others. This usually happens when you want to test a method that calls some others in the same class. So you want to keep the normal behavior of the tested method and mock the others.
In this case, the first thing to do is to consider a refactoring since most of the time this problem was caused by a bad design. If it's not the case, or if you can't do otherwise because of some development constraints, here's the solution:
In this case only the methods added with
addMockedMethod(s) will be mocked (
mockedMethod() in the example).
The others will still behave as they used to. One exception: abstract methods are conveniently mocked by default.
partialMockBuilder returns a
IMockBuilder interface. It contains various methods to easily create a partial mock.
Have a look at the javadoc.
Remark: EasyMock provides a default behavior for Object's methods (equals, hashCode, toString, finalize). However, for a partial mock, if these methods are not mocked explicitly, they will have their normal behavior instead of EasyMock default's one.
It is possible to create a mock by calling one of its constructor. This can be handy when a class method needs to be tested but the class other methods, mocked. For that you should do something like
ConstructorCalledMockTest for an example.
For some reason (usually an unsupported JVM), it is possible that EasyMock isn't able to mock a class mock in your environment. Under the hood, class instantiation is implemented with a factory pattern. In case of failure, you can replace the default instantiator with:
DefaultClassInstantiatorwhich works well with Serializable classes and otherwise tries to guess the best constructor and parameters to use.
You set this new instantiator using
ClassInstantiatorFactory.setInstantiator(). You can set back the default
Important:The instantiator is kept statically so it will stick between your unit tests. Make sure you reset it if needed.
A class mock can also be serialized. However, since it extends a serializable class, this class might have defined a special behavior
using for instance
writeObject. These methods will still be called when serializing the mock and might fail. The workaround is usually to call a constructor when creating the mock.
Also, de-serializing the mock in a different class loader than the serialization might fail. It wasn't tested.
finalize()even for class mocking. It means that you cannot record your own behavior for these methods. This limitation is considered to be a feature that prevents you from having to care about these methods.
Mock Objects can be named at creation using
mock(String name, Class<T> toMock),
strictMock(String name, Class<T> toMock) or
niceMock(String name, Class<T> toMock). The names will be shown in exception failures.
Let us write a second test. If a document is added on the class under test, we expect a call to
mock.documentAdded() on the Mock Object with the title of the document as argument:
So in the record state (before calling
replay), the Mock Object does not behave like a Mock Object, but it records method calls. After calling
replay, it behaves like a Mock Object, checking whether the expected method calls are really done.
classUnderTest.addDocument("New Document", new byte) calls the expected method with a wrong argument, the Mock Object will complain with an
All missed expectations are shown, as well as all fulfilled expectations for the unexpected call (none in this case). If the method call is executed too often, the Mock Object complains, too:
It is also possible to specify a changing behavior for a method. The methods
andThrow may be chained. As an example, we define
RuntimeExceptionfor the next four calls,
EasyMock provides a property mechanisim allowing to alter its behavior. It mainly aims at allowing to use a legacy behavior on a new version. Currently supported properties are:
Properties can be set in two ways.
easymock.propertiesfile set in the classpath default package
EasyMock.setEasyMockProperty. Constants are available in the
EasyMockclass. Setting properties in the code obviously override any property set in
The behavior for the four Object methods
finalize() cannot be changed for Mock Objects created with EasyMock, even if they are part of the interface for which the Mock Object is created.
Sometimes, we would like our Mock Object to respond to some method calls, but we do not want to check how often they are called, when they are called, or even if they are called at all. This stub behavoir may be defined by using the methods
andStubAnswer(IAnswer<T> answer) and
asStub(). The following code configures the MockObject to answer 42 to
voteForRemoval("Document") once and -1 for all other arguments:
Mock Objects may be reset by
If needed, a mock can also be converted from one type to another by calling
There is one error that we have not handled so far: If we specify behavior, we would like to verify that it is actually used. The current test would pass if no method on the Mock Object is called. To verify that the specified behavior has been used, we have to call
If the method is not called on the Mock Object, we now get the following exception:
The message of the exception lists all missed expectations.
Up to now, our test has only considered a single method call. The next test should check whether the addition of an already existing document leads to a call to
mock.documentChanged() with the appropriate argument. To be sure, we check this three times (hey, it is an example ;-)):
To avoid the repetition of
mock.documentChanged("Document"), EasyMock provides a shortcut. We may specify the call count with the method
times(int times) on the object returned by
expectLastCall(). The code then looks like:
If the method is called too often, we get an exception that tells us that the method has been called too many times. The failure occurs immediately at the first method call exceeding the limit:
If there are too few calls,
verify(mock) throws an
For specifying return values, we wrap the expected call in
expect(T value) and specify the return value with the method
andReturn(Object returnValue) on the object returned by
As an example, we check the workflow for document removal. If
ClassUnderTest gets a call for document removal, it asks all collaborators for their vote for removal with calls to
byte voteForRemoval(String title) value. Positive return values are a vote for removal. If the sum of all values is positive, the document is removed and
documentRemoved(String title) is called on all collaborators:
The type of the returned value is checked at compile time. As an example, the following code will not compile, as the type of the provided return value does not match the method's return value:
Instead of calling
expect(T value) to retrieve the object for setting the return value, we may also use the object returned by
expectLastCall(). Instead of
we may use
This type of specification should only be used if the line gets too long, as it does not support type checking at compile time.
For specifying exceptions (more exactly: Throwables) to be thrown, the object returned by
expect(T value) provides the method
andThrow(Throwable throwable). The method has to be called in record state after the call to the Mock Object for which it specifies the
Throwable to be thrown.
Unchecked exceptions (that is,
Error and all their subclasses) can be thrown from every method. Checked exceptions can only be thrown from the methods that do actually throw them.
Sometimes we would like our mock object to return a value or throw an exception that is created at the time of the actual call. Since EasyMock 2.2, the object returned by
expect(T value) provides the method
andAnswer(IAnswer answer) which allows to specify an implementation of the interface
IAnswer that is used to create the return value or exception.
IAnswer callback, the arguments passed to the mock call are available via
EasyMock.getCurrentArgument(int index). If you use these, refactorings like reordering parameters may break your tests. You have been warned.
An alternative to
IAnswer are the
andStubDelegateTo methods. They allow to delegate the call to a concrete implementation of the mocked interface that will then provide the answer. The pros are that the arguments found in
IAnswer are now passed to the method of the concrete implementation. This is refactoring safe. The cons are that you have to provide an implementation which is kind of doing a mock manually... Which is what you try to avoid by using EasyMock. It can also be painful if the interface has many methods. Finally, the type of the concrete class can't be checked statically against the mock type. If for some reason, the concrete class isn't implementing the method that is delegated, you will get an exception during the replay only. However, this case should be quite rare.
To understand correctly the two options, here is an example:
Up to this point, we have seen a mock object as a single object that is configured by static methods on the class
EasyMock. But many of these static methods just identify the hidden control of the Mock Object and delegate to it. A Mock Control is an object implementing the
So instead of
we may use the equivalent code:
The IMocksControl allows to create more than one Mock Object, and so it is possible to check the order of method calls between mocks. As an example, we set up two mock objects for the interface
IMyInterface, and we expect the calls
mock2.a() ordered, then an open number of calls to
mock2.c(), and finally
mock1.b(), in this order:
To relax the expected call counts, there are additional methods that may be used instead of
times(int min, int max)
If no call count is specified, one call is expected. If we would like to state this explicitely,
times(1) may be used.
Sometimes, it is necessary to have a Mock Object that checks the order of only some calls. In record phase, you may switch order checking on by calling
checkOrder(mock, true) and switch it off by calling
There are two differences between a strict Mock Object and a normal Mock Object:
To match an actual method call on the Mock Object with an expectation,
Object arguments are by default compared with
equals(). Arrays are
by default since 3.5 compared with
But once in a while, you will want to match you parameter in a different way. As an example, we consider the following expectation:
Here, I don't want the document received by
voteForRemovals to be equals,
I want it to be the exact same class instance coming from the cache. My current expectation
is not testing what I want.
To specify that the exact same instance is needed for this call, we use the method
same that is statically imported from the
Important: When you use matchers in a call, you have to specify matchers for all arguments of the method call.
There are a couple of predefined argument matchers available.
eq(X value, X delta)
Arrays.equals(). Available for primitive and object arrays.
startsWith(String prefix), contains(String substring), endsWith(String suffix)
matches(String regex), find(String regex)
and(X first, X second)
secondboth match. Available for all primitive types and for objects.
or(X first, X second)
secondmatch. Available for all primitive types and for objects.
valuedoes not match.
Comparable.compareTo(X o). Available for all numeric primitive types and
cmp(X value, Comparator<X> comparator, LogicalOperator operator)
comparator.compare(actual, value) operator 0where the operator is <,<=,>,>= or ==. Available for objects.
Captureparameter for later access. You can do
and(someMatcher(...), capture(c))to capture a parameter from a specific call to the method. You can also specify a
CaptureTypetelling that a given
Captureshould keep the first, the last, all or no captured values.
Sometimes it is desirable to define own argument matchers. Let's say that an argument matcher is needed that matches an exception if the given exception has the same type and an equal message. It should be used this way:
Two steps are necessary to achieve this: The new argument matcher has to be defined, and the static method
eqException has to be declared.
To define the new argument matcher, we implement the interface
org.easymock.IArgumentMatcher. This interface contains two methods:
matches(Object actual) checks whether the actual argument matches the given argument, and
appendTo(StringBuffer buffer) appends a string representation of the argument matcher to the given string buffer. The implementation is straightforward:
eqException must create the argument matcher with the given Throwable, report it to EasyMock via the static method
reportMatcher(IArgumentMatcher matcher), and return a value so that it may be used inside the call (typically
false). A first attempt may look like:
However, this only works if the method
logThrowable in the example usage accepts
Throwables, and does not require something more specific like a
RuntimeException. In the latter case, our code sample would not compile:
Java 5.0 to the rescue: Instead of defining
eqException with a
Throwable as parameter and return value, we use a generic type that extends
Mocks can be serialized at any time during their life. However, there are some obvious constraints:
During recording, a mock is not thread-safe. So a giving mock (or mocks linked to the same
IMocksControl) can only be recorded from a single thread. However, different mocks can be recorded simultaneously in different threads.
During the replay phase, mocks are by default thread-safe. This can be change for a given mock if
makeThreadSafe(mock, false) is called during the recording phase. This can prevent deadlocks in some rare situations.
checkIsUsedInOneThread(mock, true) on a mock will make sure the mock is used in only one thread and throw an exception otherwise. This can be handy to make sure a thread-unsafe mocked object is used correctly.
EasyMock jar can be used as an OSGi bundle. It exports
org.easymock.internal.matchers packages. However, to import the two latter, you need to specify the
poweruser attribute at true (
poweruser=true). These packages are meant to be used to extend EasyMock so they usually don't need to be imported.
EasyMock 3 still has a Class Extension project (although deprecated) to allow an easier migration from EasyMock 2 to EasyMock 3. It is a source not a binary compatibility. So the code will need to be recompiled.
EasyMock 2.1 introduced a callback feature that has been removed in EasyMock 2.2, as it was too complex. Since EasyMock 2.2, the
IAnswer interface provides the functionality for callbacks.