Question

I have huge class that I need to build stub for.

To give you picture it is Messages class of the GWT. Often this is class with dozens of methods that return String.

With JMock I can do stubbing, but I will end with allowing each method... This is not something that I would like to see.

Is there something that will automatically build the stubs for each method? I need this methods to return something predefined, like empty string, but I will be happy with any suggestions.

Was it helpful?

Solution

In JMock you can allow the methods you care about with explicit results and then allow any other method of the messages object with an allowing statement that does not include a method. E.g.:

allowing(m).getBlah("something");
    will(returnValue("foo"));
allowing(m); // matches anything else, will return some default value if called 

But...

If you are just stubbing a bunch of getter methods, a mock object framework is the wrong tool to use. Mock objects are used for testing that the object under test sends the correct commands to neighbouring objects to effect change in its environment.

It's often easier to create a stub class if the interface that only contains getters. Or you can use Usurper to generate stubs automatically.

OTHER TIPS

For an interface you can use the functionality of java.lang.reflect.Proxy. Assuming that you want to stub answers for the MessageConstants class, the code will look similar to:

        InvocationHandler handler = new InvocationHandler() {

        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

            if (String.class.equals(method.getReturnType()))
                return "proxy generated method return";

            throw new AbstractMethodError("Not implemented");
        }
    };
    Class<?> proxyClass = Proxy.getProxyClass(MessageConstants.class.getClassLoader(), new Class[] { MessageConstants.class });
    MessageConstants messageConstants = (MessageConstants) proxyClass.getConstructor(new Class[] {InvocationHandler.class}).newInstance(new Object[] { handler });

    System.out.println(messageConstants.description());

    messageConstants.getBoolean("someBoolean");

and will result in

proxy generated method return
Exception in thread "main" java.lang.Error: Not implemented
at xxx.Application$1.invoke(Application.java:48)
at $Proxy0.getBoolean(Unknown Source)
at xxx.Application.main(Application.java:64)

The InvocationHandler drives the stubbing, while the rest is just plumbing.

Glad to see you found an answer. Just for further info, jMock allows quite flexible specifications of how you match methods, see http://www.jmock.org/match-object-or-method.html. For example, you can do this sort of thing:

allowing (any(Object.class)).method("get.*").withNoArguments();

to match any getter.

S

If you use EasyMock, you only need to specify behavior/expectations/stubs for the methods you actually expect to be called and used.

After using both JMock and EasyMock, I have to say that EasyMock's API is about 10x easier to use, and since the interface is mostly statically-typed, it's refactoring safe as well (you are using Strings for method names, etc.).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top