Throwing exception out of mocked code confused expected exception handling
GoogleCodeExporter opened this issue · comments
Google Code Exporter commented
@Stub private Exception throwable;
@Stub private RuntimeException sanitisedException;
@Specification(expectedException = KahunaException.class)
public void delegatesToTheExceptionSanitizerForAllExceptions() throws
Throwable {
expect.that(new Expectations() {
{
one(call).proceed(); will(throwException(throwable));
}
});
aspect.sanitize(call);
}
Results in:
java.lang.RuntimeException
Original issue reported on code.google.com by tomjad...@gmail.com
on 25 Nov 2007 at 10:27
Google Code Exporter commented
From Nick:
@RunWith(InstinctRunner.class)
public final class InstinctFailContext {
private Runnable mockRunnable;
@Specification
public void shouldReportNicerFailsInIntellij() {
expect.that(new Expectations() {
{
one(mockRunnable).run();
}
});
new Thing().foo();
}
private static final class Thing {
public void foo() {
throw new RuntimeException("I SHOULD GET SEEN");
}
}
}
The output in intellij is:
not all expectations were satisfied
expectations:
expected once, never invoked: mockRunnable.run(); returns a default value
at org.jmock.Mockery.assertIsSatisfied(Mockery.java:196)
at
com.googlecode.instinct.internal.expect.behaviour.JMock2MockeryImpl.verify(JMock
2MockeryImpl.java:76)
at com.googlecode.instinct.expect.behaviour.Mocker.verify(Mocker.java:57)
The key problem here is that the exception thrown by 'new
Thing().foo()' is silently ignored. This is a massive annoyance when
working with mocked objects. Some of the reasons why we see this:
* unexpected invocation exceptions
* null pointer exceptions (because of reflector injection failure)
I've isolated the point in Instinct where the esception is discarded,
SpecificationRunnerImpl lines 61-74.
This is my horrible fix:
private void runSpecificationLifecycle(final Object contextInstance,
final SpecificationMethod specificationMethod) {
Mocker.reset();
boolean caught = false;
actorAutoWirer.autoWireFields(contextInstance);
try {
runMethods(contextInstance,
specificationMethod.getBeforeSpecificationMethods());
runSpecificationMethod(contextInstance, specificationMethod);
} catch (RuntimeException e) {
caught = true;
throw e;
} finally {
try {
runMethods(contextInstance,
specificationMethod.getAfterSpecificationMethods());
} finally {
// Note. We need to make sure we capture and report
all errors correctly.
if (!caught) {
Mocker.verify();
}
}
}
}
Original comment by tomjad...@gmail.com
on 29 Jul 2008 at 11:44
Google Code Exporter commented
Another one from Nick:
package com.vlc;
import static com.googlecode.instinct.expect.Expect.expect;
import com.googlecode.instinct.integrate.junit4.InstinctRunner;
import com.googlecode.instinct.marker.annotate.Specification;
import org.jmock.Expectations;
import org.junit.runner.RunWith;
@RunWith(InstinctRunner.class)
public final class InstinctFailContext {
private Runnable mockRunnable;
@Specification(expectedException = IllegalArgumentException.class)
public void shouldReportNicerFailsInIntellij() {
expect.that(new Expectations() {
{
one(mockRunnable).run();
}
});
new Thing().foo();
}
private static final class Thing {
public void foo() {
throw new IllegalArgumentException("HERE");
}
}
}
Original comment by tomjad...@gmail.com
on 31 Jul 2008 at 1:17
Google Code Exporter commented
Above code from: http://gist.github.com/3232
Original comment by tomjad...@gmail.com
on 31 Jul 2008 at 1:18
Google Code Exporter commented
Fixed...
Original comment by tomjad...@gmail.com
on 7 Aug 2008 at 5:58
- Changed state: Fixed