dhamini-poornachandra / mockito

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

Cannot mock method to throw instance of Throwable #284

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
Motivation:
For particularly important code, I want to check that it reacts correctly when 
strange things happen.

Testing what happens when a method throws strange exceptions is crucial in 
cleanup code etc.

Admittedly, no code should ever actually throw instances of Throwable. However, 
the code under test should not be clever about the concrete class of thrown 
exceptions.

At the very least, the suggested feature will permit testing that Throwable is 
not being caught.

This is (IMHO) a minor change, and I don't see any reason why Mockito should 
not support this?

What steps will reproduce the problem?
1. Mockito.doThrow(new Throwable("test")).when(mymock).mymethod();

What is the expected output? What do you see instead?
Expected: mymock should throw the indicated Throwable when mymethod() is 
invoked.
Actual: AnswersValidator.validateException() fails because it only considers 
RuntimeException and Error as unchecked exceptions - instances of Throwable get 
treated like checked exceptions (which must be listed in the mymethod() throws 
clause).

What version of the product are you using? On what operating system?
Mockito 1.8.4 on Windows XP.

Please provide any additional information below.
In AnswersValidator.validateException(), replace line 65:
        if (throwable instanceof RuntimeException || throwable instanceof Error) {

by

        if (throwable instanceof RuntimeException || throwable instanceof Error || throwable.getClass() == Throwable.class) {

Original issue reported on code.google.com by mlauri...@gmail.com on 27 Oct 2011 at 2:54

GoogleCodeExporter commented 8 years ago
Hey :)

>I don't see any reason why Mockito should not support this?

Here's why: The only exceptions your code can throw are Errors or Runtimes. All 
other kinds you must handle yourself because otherwise your code will not 
compile. So your code cannot throw checked exceptions that are not declared. 
Java and JVM won't let you do it.

Also, I don't think it is possible to implement. Even if you remove the 
validation check you will most likely face some awkward exception. Feel free to 
test it with mockito code base and our integration tests.

Makes sense?

Original comment by szcze...@gmail.com on 27 Oct 2011 at 7:41

GoogleCodeExporter commented 8 years ago
I don't understand what you mean by "The only exceptions your code can throw 
are Errors or Runtimes." - it is possible to throw Throwable - try it! Very 
simple: throw new Throwable("test"); - there you go!

Did you look at the suggested fix? I never suggested removing the validation 
check, where did that come from? The suggested fix simply includes instances of 
Throwable as a valid exception that a mock can throw, I don't see why that 
should not be allowed?

As to "I don't think it is possible to implement.", I included a very simple 
fix in the issue, if you don't think that will work, could you explain why?

Granted, it is a bit strange for code to throw Throwable, but since Java allows 
it, I don't see why Mockito should not support testing this behaviour.

I included the fix to minimise the work you have to do, if there's anything 
else I can do, I'll be happy to help. I suppose there should be a unit test to 
go with it:

    @Test
    public void shouldAcceptThrowable() {
        // when
        Invocation invocation = Mockito.mock(Invocation.class);
        ThrowsException answer = new ThrowsException(new Throwable("test"));

        // when
        new AnswersValidator().validate(answer, invocation);

        // then
        Mockito.verifyNoMoreInteractions(invocation);
    }

Note that this test will fail if you do not include my fix above.

Original comment by mlauri...@gmail.com on 28 Oct 2011 at 5:46

GoogleCodeExporter commented 8 years ago
>it is possible to throw Throwable - try it! Very simple: throw new 
Throwable("test"); - there you go!
In groovy, yes :) In java it will not compile. Unless you declare this 
exception at method signature (which will solve your mockito problem right of 
the bat).

>Note that this test will fail if you do not include my fix above.
I don't think the fix does it. You're telling byte-engineered method to throw 
Throwable that is not declared. The result most likely will be awkward jvm 
runtime error. It's like telling int-returning method to return String.

Those are my guesses. Did you try your fix with mockito codebase, is it working?

Cheers :)

Original comment by szcze...@gmail.com on 29 Oct 2011 at 9:19

GoogleCodeExporter commented 8 years ago
Oops - I see your point.

Sorry to waste your time.

Go ahead and discard/reject this issue, nothing to see, move along. :-)

Original comment by mlauri...@gmail.com on 31 Oct 2011 at 3:17

GoogleCodeExporter commented 8 years ago

Original comment by szcze...@gmail.com on 1 Nov 2011 at 11:14