|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||
java.lang.Objectcheesymock.Cheesy
public class Cheesy
The user should have to type as little as possible.
Let's say you're writing an application and want to write some
unit tests. For one of your tests you need to supply an instance
of HttpServletRequest, which puts you
in kind of pickle. You have no concrete implementation of that
class, since that's usually provided by a sevlet container. So
what do you do? Well, you could write your own simple
implementation of HttpServletRequest and use that in your test
case. It's not that hard, especially if you're using one of the
modern IDEs that can generate most of the code for you.
It seems a bit wasteful, though. You know for a fact that your
test will only ever call a single method (let's say javax.sevlet.http.HttpServletRequest#getRequestURI()) and only
requires a trivial return value (let's say
"www.myserver.com/myApp/myServlet/"). Why should you have to
create a big honkin' class just for that?
Well, it turns out you don't have to. With CheesyMock you can get an instance of HttpServletRequest just by writing something like this:
HttpServletRequest req = Cheesy.mock(HttpServletRequest.class);
Voila! One request instance coming up. But what about the
return value? We need the call req.getRequestURI()
to actually return something useful. Well, in that case we also
need to supply a delegate object. If you call a method on
the mock that's also defined in the delegate (i.e. the name,
argument list and return type are equivalent), then the delegate
method will be called and its return value will be returned from
the mock method call.
A delegate object can be any object at all, so for this case we define a new class inline:
HttpServletRequest req = Cheesy.mock(HttpServletRequest.class, new Object() {
public String getRequestURI() {
return "www.myserver.com/myApp/myServlet";
}
});
Pretty neat, huh? But we can do even better. CheesyMock doesn't
care about visibility modifiers on methods, so you can safely
drop the public, which makes it a bit
shorter. Also, CheesyMock supplies a very simple standard
delegate called (you guessed it) Delegate, which can be
used instead of Object. That in itself doesn't save any
keystrokes, but Delegate has an alias (well, a subclass really)
called simply D. Similarly, Cheesy also has an
alias called C So the statement above could be written
as:
HttpServletRequest req = C.mock(HttpServletRequest.class, new D() {
String getRequestURI() {
return "www.myserver.com/myApp/myServlet";
}
});
Also, if you want it really short and sweet, you can take advantage of the JavaBean-style method accessors (see below) and just write:
HttpServletRequest req = C.mock(HttpServletRequest.class, new D() {
String requestURI = "www.myserver.com/myApp/myServlet";
});
CheesyMock recognizes JavaBean-style accessor methods in your interfaces and automatically tries to match them against the members of your delegate object. For example, if you have following interface:
public interface Example {
public String getName();
public void setName(String name);
}
then you will be able to declare your delegate as simple as this:
Example mock = Cheesy.mock(Example.class, new Object() {
String name = "foo";
});
mock.getName(); // returns "foo"
mock.setName("bar");
mock.getName(); // returns "bar"
CheesyMock employs a simple lifecycle model for mock objects:
Create the mock using Cheesy#mock() or other equivalent
method. During this stage you may get exceptions if your delegate
object is not accepted by the current set of validators. For
example, if you are using the 'strict' validators and implement a
method in your delegate that is not in the interface, you will get
an IllegalArgumentException.
Use the mock objects in your tests; call various methods, use
getters and setterns and so on. As above, the chosen validators may
throw exceptions. For example, with the 'strict' validators you
will get an UnsupportedOperationException if you
call a method on the mock object that is not defined by the
delegate.
Finally, after you are done with the mock object you may call
Cheesy.check() once to check its integrity. This is
optional, but highly recommended. As above, you may get exceptions
during this stage. For example, if you are using the 'strict'
validators you will get an exception if you have not called all
methods defined in the delegate object.
Additionally, any method annotated with Check in the
delegate object will be invoked. This is a convenient way to
perform custom validation of the delegate object, for example
checking that the internal state is as expected.
CheesyMock can be used to create mock objects from regular java classes, something which is not possible using the dynamic proxy mechanism in the JDK. For this to work, you need a recent version of CGLIB (http://cglib.sourceforge.net/) on the class path at runtime.
Version 1.0 used log4j in some places, but for version 1.1 this dependency has been removed. Other than that, CheesyMock doesn't depend on any external jars at all.
As mentioned above, you need CGLIB on the class path if you intend to mock regular classes. CheesyMock works fine without it, but you are then restricted to creating mocks from interfaces only.
C,
Delegate,
D| Constructor Summary | |
|---|---|
protected |
Cheesy()
|
| Method Summary | ||
|---|---|---|
static void |
check(Object... mocks)
Check the state of a previously instantiated and used mock object. |
|
static
|
mock(Class<T> interfaceToImplement)
Create a mock object with a 'normal' set of validators. |
|
static
|
mock(Class<T> interfaceToImplement,
Object delegate)
Create a mock object with a 'normal' set of validators. |
|
static
|
mock(Class<T> interfaceToImplement,
Validator[] validators,
Object delegate,
DefaultReturn defaultReturn)
|
|
static
|
mockRelaxed(Class<T> interfaceToImplement)
Create a mock object without any validation except for CheckDelegate. |
|
static
|
mockRelaxed(Class<T> interfaceToImplement,
Object delegate)
Create a mock object without any validation except for CheckDelegate. |
|
static
|
mockStrict(Class<T> interfaceToImplement)
Create a mock object with a 'strict' set of validators. |
|
static
|
mockStrict(Class<T> interfaceToImplement,
Object delegate)
Create a mock object with a 'strict' set of validators. |
|
| Methods inherited from class java.lang.Object |
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
| Constructor Detail |
|---|
protected Cheesy()
| Method Detail |
|---|
public static <T> T mock(Class<T> interfaceToImplement,
Validator[] validators,
Object delegate,
DefaultReturn defaultReturn)
public static <T> T mock(Class<T> interfaceToImplement,
Object delegate)
public static <T> T mock(Class<T> interfaceToImplement)
public static <T> T mockStrict(Class<T> interfaceToImplement,
Object delegate)
public static <T> T mockStrict(Class<T> interfaceToImplement)
public static <T> T mockRelaxed(Class<T> interfaceToImplement,
Object delegate)
CheckDelegate.
public static <T> T mockRelaxed(Class<T> interfaceToImplement)
CheckDelegate.
public static void check(Object... mocks)
mocks - one or more mock objects
|
|||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | ||||||||