Skip to content

Commit

Permalink
Fixes mockito#2201 : Fixed checking of declared exceptions. In case w…
Browse files Browse the repository at this point in the history
…hen parent contains throws keyword on its method and child overrides this method removing throws, it should be possible to mock throwing exception from child
  • Loading branch information
Andrey Kozel committed Jan 23, 2022
1 parent faa6e92 commit 264e2fa
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 2 deletions.
Expand Up @@ -6,6 +6,8 @@

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Objects;

import org.mockito.internal.invocation.AbstractAwareMethod;
import org.mockito.internal.util.MockUtil;
Expand All @@ -25,14 +27,33 @@ public InvocationInfo(InvocationOnMock theInvocation) {
}

public boolean isValidException(Throwable throwable) {
if (isValidException(method, throwable)) {
return true;
}

return Arrays.stream(method.getDeclaringClass().getInterfaces())
.map(this::getMethodOrNull)
.filter(Objects::nonNull)
.anyMatch(parentMethod -> isValidException(parentMethod, throwable));
}

private Method getMethodOrNull(Class<?> parent) {
try {
return parent.getMethod(method.getName(), method.getParameterTypes());
} catch (NoSuchMethodException e) {
// ignore interfaces that doesn't have such a method
return null;
}
}

private boolean isValidException(Method method, Throwable throwable) {
Class<?>[] exceptions = method.getExceptionTypes();
Class<?> throwableClass = throwable.getClass();
for (Class<?> exception : exceptions) {
if (exception.isAssignableFrom(throwableClass)) {
return true;
}
}

return false;
}

Expand Down
Expand Up @@ -30,6 +30,7 @@ public class InvocationBuilder {
private int sequenceNumber = 0;
private Object[] args = new Object[] {};
private Object mock = Mockito.mock(IMethods.class);
private Class<?> mockClass = IMethods.class;
private Method method;
private boolean verified;
private List<Class<?>> argTypes;
Expand Down Expand Up @@ -57,7 +58,7 @@ public Invocation toInvocation() {

try {
method =
IMethods.class.getMethod(
mockClass.getMethod(
methodName, argTypes.toArray(new Class[argTypes.size()]));
} catch (Exception e) {
throw new RuntimeException(
Expand Down Expand Up @@ -115,6 +116,12 @@ public InvocationBuilder mock(Object mock) {
return this;
}

public InvocationBuilder mockClass(Class<?> mockClass) {
this.mockClass = mockClass;
this.mock = mock(mockClass);
return this;
}

public InvocationBuilder method(Method method) {
this.method = method;
return this;
Expand Down
Expand Up @@ -15,6 +15,7 @@
import org.mockito.internal.invocation.InvocationBuilder;
import org.mockito.invocation.Invocation;
import org.mockitousage.IMethods;
import org.mockitousage.MethodsImpl;

public class InvocationInfoTest {

Expand All @@ -29,6 +30,20 @@ public void should_know_valid_throwables() throws Exception {
assertThat(info.isValidException(new CharacterCodingException())).isTrue();
}

@Test
public void should_mark_interface_overridden_exceptions_as_valid() {
// when
Invocation invocation =
new InvocationBuilder()
.method("throwsRemovedInSubclass")
.mockClass(MethodsImpl.class)
.toInvocation();
InvocationInfo info = new InvocationInfo(invocation);

// then
assertThat(info.isValidException(new CharacterCodingException())).isTrue();
}

@Test
public void should_know_valid_return_types() throws Exception {
assertThat(
Expand Down
2 changes: 2 additions & 0 deletions src/test/java/org/mockitousage/IMethods.java
Expand Up @@ -159,6 +159,8 @@ String simpleMethod(

String canThrowException() throws CharacterCodingException;

String throwsRemovedInSubclass() throws CharacterCodingException;

String oneArray(String[] array);

void varargsString(int i, String... string);
Expand Down
5 changes: 5 additions & 0 deletions src/test/java/org/mockitousage/MethodsImpl.java
Expand Up @@ -303,6 +303,11 @@ public String canThrowException() throws CharacterCodingException {
return null;
}

@Override
public String throwsRemovedInSubclass() {
return null;
}

public String oneArray(String[] array) {
return null;
}
Expand Down

0 comments on commit 264e2fa

Please sign in to comment.