Skip to content

Calling getExceptionTypes() on concrete object that is used as interface doesn't return exception types from interface #2201

Description

@henrykuijpers

org.mockito.internal.stubbing.answers.InvocationInfo#isValidException is doing validation on the exception types that can be thrown from this method.

In my codebase, I'm programming against an interface, but in fact, a spy is created from an instance that is implementing the interface, that drops the exception types that that implementation does not throw. However, the code that is calling the interface is of course unaware of that fact. Also, that implementation is a mock implementation (a real mock implementation, not a Mockito mock()/spy() instance).

A testcase here:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.exceptions.base.MockitoException;
import org.mockito.junit.jupiter.MockitoExtension;

import java.io.IOException;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.spy;

@ExtendWith(MockitoExtension.class)
public class MockitoExceptionTypesIssue {
    @Test
    void exceptionTypeIoExceptionShouldBeMockableForObjectBeingSpyedOn() {
        final I x = spy(new C());
        final IOException ioException = new IOException("Oh my god!");
        final MockitoException e = assertThrows(
                MockitoException.class,
                () -> doThrow(ioException)
                        .when(x)
                        .m());
        assertEquals("\n" +
                "Checked exception is invalid for this method!\n" +
                "Invalid: " + ioException,
                e.getMessage()
        );
    }

    interface I {
        void m() throws IOException;
    }

    static class C implements I {
        public void m() {
            // no-op
        }
    }
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions