cheesymock
Class Cheesy

java.lang.Object
  extended by cheesymock.Cheesy
Direct Known Subclasses:
C

public class Cheesy
extends Object

CheesyMock

CheesyMock is a small and simple library for creating mock objects from Java interfaces. It has but one design goal:
The user should have to type as little as possible.

A Use Case Example

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";
 });

JavaBean-style method accessors

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"

The check() method

CheesyMock employs a simple lifecycle model for mock objects:

  1. 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.

  2. 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.

  3. 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.

Validators

TBA

Mocking regular java classes

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.

Dependencies

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.

Author:
fredrik
See Also:
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
<T> T
mock(Class<T> interfaceToImplement)
          Create a mock object with a 'normal' set of validators.
static
<T> T
mock(Class<T> interfaceToImplement, Object delegate)
          Create a mock object with a 'normal' set of validators.
static
<T> T
mock(Class<T> interfaceToImplement, Validator[] validators, Object delegate, DefaultReturn defaultReturn)
           
static
<T> T
mockRelaxed(Class<T> interfaceToImplement)
          Create a mock object without any validation except for CheckDelegate.
static
<T> T
mockRelaxed(Class<T> interfaceToImplement, Object delegate)
          Create a mock object without any validation except for CheckDelegate.
static
<T> T
mockStrict(Class<T> interfaceToImplement)
          Create a mock object with a 'strict' set of validators.
static
<T> T
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

Cheesy

protected Cheesy()
Method Detail

mock

public static <T> T mock(Class<T> interfaceToImplement,
                         Validator[] validators,
                         Object delegate,
                         DefaultReturn defaultReturn)

mock

public static <T> T mock(Class<T> interfaceToImplement,
                         Object delegate)
Create a mock object with a 'normal' set of validators.


mock

public static <T> T mock(Class<T> interfaceToImplement)
Create a mock object with a 'normal' set of validators.


mockStrict

public static <T> T mockStrict(Class<T> interfaceToImplement,
                               Object delegate)
Create a mock object with a 'strict' set of validators.


mockStrict

public static <T> T mockStrict(Class<T> interfaceToImplement)
Create a mock object with a 'strict' set of validators.


mockRelaxed

public static <T> T mockRelaxed(Class<T> interfaceToImplement,
                                Object delegate)
Create a mock object without any validation except for CheckDelegate.


mockRelaxed

public static <T> T mockRelaxed(Class<T> interfaceToImplement)
Create a mock object without any validation except for CheckDelegate.


check

public static void check(Object... mocks)
Check the state of a previously instantiated and used mock object.

Parameters:
mocks - one or more mock objects


Copyright © 2009. All Rights Reserved.