Forgus / spock

Automatically exported from code.google.com/p/spock
0 stars 0 forks source link

thrown check doesn't handle checked exceptions with mocks #298

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
In a Mock throw a checked exception

   1 * repository.findOne(42l) >> {throw new NotFoundException("oh no!")}

In the "then" clause use the thrown check to verify the exception

   thrown(NotFoundException)

The result is a test failure because groovy wraps the exception with 
UndeclaredThrowableException. I think thrown should check for this exception 
type and check if the type matches the "undeclaredThrowable" property of 
UndeclaredThrowableException.

Exception:

Expected exception com.fl.rest.NotFoundException, but got 
java.lang.reflect.UndeclaredThrowableException
    at spock.lang.Specification.thrown(Specification.java:232)
    at ...###Test.read a bean(###ControllerTest.groovy:47)
Caused by: java.lang.reflect.UndeclaredThrowableException
    at ...###Controller.readBean_aroundBody0(###Controller.java:32)
    at ...###Controller.readBean_aroundBody1$advice(###Controller.java:31)
    at ...###Controller.readBean(###Controller.java:1)
    at ...###ControllerTest.read a bean(###ControllerTest.groovy:43)
Caused by: ....NotFoundException: oh no!
    at ...###ControllerTest.read a bean_closure3(###ControllerTest.groovy:46)
    at groovy.lang.Closure.call(Closure.java:412)
    at org.spockframework.util.GroovyRuntimeUtil.invokeClosure(GroovyRuntimeUtil.java:130)
    at org.spockframework.mock.CodeResultGenerator.generateSingle(CodeResultGenerator.java:38)
    at org.spockframework.mock.SingleResultGenerator.generate(SingleResultGenerator.java:28)
    at org.spockframework.mock.ResultGeneratorChain.generate(ResultGeneratorChain.java:46)
    at org.spockframework.mock.MockInteraction.accept(MockInteraction.java:60)
    at org.spockframework.mock.MockInteractionDecorator.accept(MockInteractionDecorator.java:41)
    at org.spockframework.mock.InteractionScope$1.accept(InteractionScope.java:38)
    at org.spockframework.mock.MockController.dispatch(MockController.java:42)
    at org.spockframework.mock.DefaultMockFactory$1.invoke(DefaultMockFactory.java:70)
    ... 4 more

What version of Spock and Groovy are you using?
0.6-groovy-1.8

Please provide any additional information below. You can also assign
labels.

It's a simple change to the thrown method of Specification that would make 
working with checked exceptions & mocks a lot easier.

Original issue reported on code.google.com by ota...@otatop.com on 11 Feb 2013 at 4:37

GoogleCodeExporter commented 8 years ago
A one liner fix would be the following code added to the top of the thrown 
method. 

def realException = exception instanceof UndeclaredThrowableException ?  
exception.undeclaredThrowable : exception;

... 

Original comment by ota...@otatop.com on 11 Feb 2013 at 5:15

GoogleCodeExporter commented 8 years ago
The problem stems from the fact that you are throwing a checked exception from 
a method that doesn't declare one. We should probably allow that for a 
GroovyMock() (because Groovy doesn't have checked exceptions), but I'm unsure 
if we should allow the same for a Mock().

Original comment by pnied...@gmail.com on 21 Feb 2013 at 5:38

GoogleCodeExporter commented 8 years ago
From what I've found on the Internets about UndeclaredThrowableException, this 
is actually Java7 doing the wrapping, and it happens when a dynamic proxy 
(which is what Mocks and Closures are) throws a checked exception that isn't 
declared on the method being proxied.

Catching and unwrapping so that the Throws clause works correctly is on'y 1/2 
of the battle.

Original comment by cdes...@gmail.com on 27 Jan 2015 at 4:27