views:

213

answers:

4

Hi, 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.

A: 

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

matt b
Thanks, but in this field JMock and EasyMock are the same... Both provide statically typed interfaces.. And I have looked paticular feature which is something that matches everything on the interface...
Mike Chaliy
perhaps thats a JMock 1 vs JMock 2 change then, I've only used version 1...
matt b
Yes. We finally learned from Tammo and got rid of the string method names -- although there are things we lost in that trade-off
Steve Freeman
+1  A: 

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.

Nat
Thanks for allowing(m); this is one I looked for.. Regarding choice of tooling, the problem with stub class is that I need to refresh it every time when I did something on actual interface... This is why I need something that will automatically create stubs on the fly.Usurper is good, I will try this.
Mike Chaliy
+1  A: 

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.

Robert Munteanu
This is highly educable answer, sorry but I cannot mark two answers.. Thank you very much.
Mike Chaliy
+1  A: 

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

Steve Freeman
thanks, I will try this.
Mike Chaliy