catch exception library not working as expected. What is wrong with this code below?

I have a JUnit 4 Test and I am using https://code.google.com/p/catch-exception/ library

@Test
public void testInvalidArgument() throws Exception{

    verifyException(new Operation("" , "."), IllegalArgumentException.class);
    verifyException(new Operation(null , null), NullPointerException.class);

}

Its attempting the verify that the constructor throws the said exceptions. But my test always fails by throwing the said exception instead of succeeding by verifying the exception.

My class under test is

@SuppressWarnings("serial")
@GwtCompatible
public class Operation implements Serializable {

    private static Logger logger = Logger.getLogger(Operation.class.getName());

    private  String                 name;
    private HashMap<String, Serializable>       parameters;
    private String interfaceName ;

    /**
     * 
     * @param full expects an fully qualified operation name e.g. interface.operation . Parses and separates the interface and operation names
     * 
     * Throws Exception if either is null
     * 
     */
    public Operation(final String full) throws IllegalArgumentException , NullPointerException {
        interfaceName = checkValidInterfaceName(full.substring(0 , full.indexOf('.') ));
        name = checkValidOperationName(full.substring(full.indexOf('.') + 1, full.length()  ));
    }

    /**
     * an Operation with the same name as Action needs to exist. Actions are client side tokens used to identify components and stuff
     * @param action
     */

    public Operation(final String inter, final String string) throws IllegalArgumentException , NullPointerException {
        name = checkValidOperationName(string)  ;
        interfaceName = checkValidInterfaceName(inter) ;
    }


    public String checkValidInterfaceName(final String in) throws IllegalArgumentException{

        checkNotNull (in) ;

        if(in.isEmpty()  || in.lastIndexOf(' ') != -1 || in.lastIndexOf('.') != -1)
            throw new IllegalArgumentException("Not a valid interface name") ;
        else return in ;

    }

    public String checkValidOperationName(final String op) throws IllegalArgumentException{

        checkNotNull(op);

        if(op.isEmpty()  || op.lastIndexOf(' ') != -1 || op.lastIndexOf('.') != -1)
            throw new IllegalArgumentException("Not a valid operation name") ;

        else return op ;

    }


    @SuppressWarnings("unchecked")
    @Override
    public Operation clone() {
        final Operation clone = new Operation(this.getInterfaceName() , this.getName());
        try {

            if (parameters != null) {
                final HashMap<String, Serializable> map = (HashMap<String, Serializable>) parameters.clone();
                if (map != null)
                    clone.setParameters(map);
            }
        } catch (final Exception e) {
            logger.log(Level.WARNING, "Exception in cloning Operation - " + clone.getInterfaceName() + clone.getName()  );;
        }
        return clone;
    }

    public String getFullyQualifiedName(){
        return getInterfaceName() + "." +  getName();
    }

    public String getInterfaceName() {
        return interfaceName ;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    public HashMap<String, Serializable> getParameters() {
        return parameters;
    }

    public void setInterface(final String in){
        interfaceName = in ;
    }

    public void setName(final String name) {
        this.name = name;
    }

    public void setParameters(final HashMap<String, Serializable> parameters) {
        this.parameters = parameters;
    }
}
Jon Skeet
people
quotationmark

I haven't used the library myself, but it seems reasonably clear why your usage would fail: your code for the first statement is equivalent to:

Operation op = new Operation("" , ".");
verifyException(op, IllegalArgumentException.class);

Think about it - the first line of that is going to throw the exception, so there's nothing the second line can do about it.

As far as I can tell, verifyException is designed to return something you can then call a "bad" operation on, and the returned fake will delegate the call and check the exception appropriately. I can't see how this would work for constructor calls, basically.

Indeed, the documentation you linked to explicitly states that:

Catch-exception does not provide an API to to catch exceptions that are thrown by constructors. Use try-catch-blocks instead. Alternatively, you can use the builder pattern if this makes sense anyway for your application

(Then there's an example.)

I strongly expect that with Java 8 bringing lambda expressions to Java, unit test frameworks will start using those so you'll be able to write something like:

// Not valid yet as far as I know! (But likely to be coming to a test framework
// near you soon...)
assertThrows(IllegalArgumentException.class, () -> new Operation("", "."));

people

See more on this question at Stackoverflow