Skip to content

Commit

Permalink
Support for return type 'Void' in DoesNothingAnswer (mockito#933)
Browse files Browse the repository at this point in the history
* Fixes mockito#927 methods with return type 'Void' are treated now like void
methods

* Refactored DoesNothing and added tests to verify its validation
behaviour in case of void/Void methods.
  • Loading branch information
ChristianSchwarz authored and TimvdLippe committed Feb 7, 2017
1 parent 3e9a94b commit 275586e
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 16 deletions.
13 changes: 11 additions & 2 deletions src/main/java/org/mockito/internal/stubbing/StubberImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@

import static org.mockito.internal.exceptions.Reporter.notAMockPassedToWhenMethod;
import static org.mockito.internal.exceptions.Reporter.nullPassedToWhenMethod;
import static org.mockito.internal.stubbing.answers.DoesNothing.doesNothing;

import java.util.LinkedList;
import java.util.List;

import org.mockito.internal.stubbing.answers.CallsRealMethods;
import org.mockito.internal.stubbing.answers.DoesNothing;
import org.mockito.internal.stubbing.answers.Returns;
import org.mockito.internal.stubbing.answers.ThrowsException;
import org.mockito.internal.stubbing.answers.ThrowsExceptionClass;
Expand All @@ -24,6 +24,7 @@ public class StubberImpl implements Stubber {

private final List<Answer<?>> answers = new LinkedList<Answer<?>>();

@Override
public <T> T when(T mock) {
if (mock == null) {
throw nullPassedToWhenMethod();
Expand All @@ -37,10 +38,12 @@ public <T> T when(T mock) {
return mock;
}

@Override
public Stubber doReturn(Object toBeReturned) {
return doReturnValues(toBeReturned);
}

@Override
public Stubber doReturn(Object toBeReturned, Object... nextToBeReturned) {
return doReturnValues(toBeReturned).doReturnValues(nextToBeReturned);
}
Expand All @@ -56,6 +59,7 @@ private StubberImpl doReturnValues(Object... toBeReturned) {
return this;
}

@Override
public Stubber doThrow(Throwable... toBeThrown) {
if(toBeThrown == null) {
answers.add(new ThrowsException(null));
Expand All @@ -67,10 +71,12 @@ public Stubber doThrow(Throwable... toBeThrown) {
return this;
}

@Override
public Stubber doThrow(Class<? extends Throwable> toBeThrown) {
return doThrowClasses(toBeThrown);
}

@Override
public Stubber doThrow(Class<? extends Throwable> toBeThrown, Class<? extends Throwable>... nextToBeThrown) {
return doThrowClasses(toBeThrown).doThrowClasses(nextToBeThrown);
}
Expand All @@ -82,16 +88,19 @@ private StubberImpl doThrowClasses(Class<? extends Throwable>... toBeThrown) {
return this;
}

@Override
public Stubber doNothing() {
answers.add(new DoesNothing());
answers.add(doesNothing());
return this;
}

@Override
public Stubber doAnswer(Answer answer) {
answers.add(answer);
return this;
}

@Override
public Stubber doCallRealMethod() {
answers.add(new CallsRealMethods());
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,16 @@ public class DoesNothing implements Answer<Object>, ValidableAnswer, Serializabl

private static final long serialVersionUID = 4840880517740698416L;

public Object answer(InvocationOnMock invocation) throws Throwable {
private static final DoesNothing SINGLETON = new DoesNothing();

private DoesNothing() {}

public static DoesNothing doesNothing(){
return SINGLETON;
}

@Override
public Object answer(InvocationOnMock invocation){
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,13 @@ public boolean isValidReturnType(Class<?> clazz) {
}
}

/**
* Returns {@code true} is the return type is {@link Void} or represents the pseudo-type to the keyword {@code void}.
* E.g: {@code void foo()} or {@code Void bar()}
*/
public boolean isVoid() {
return this.method.getReturnType() == Void.TYPE;
Class<?> returnType = this.method.getReturnType();
return returnType == Void.TYPE|| returnType == Void.class;
}

public String printMethodReturnType() {
Expand All @@ -62,6 +67,7 @@ public boolean isDeclaredOnInterface() {
return method.getDeclaringClass().isInterface();
}

@Override
public boolean isAbstract() {
return (method.getModifiers() & Modifier.ABSTRACT) != 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import static java.util.Arrays.asList;
import static org.junit.Assert.assertEquals;
import static org.mockito.internal.stubbing.answers.DoesNothing.doesNothing;

public class UnusedStubbingsTest extends TestBase {

Expand All @@ -32,8 +33,8 @@ public void no_unused_stubbings() throws Exception {
public void unused_stubbings() throws Exception {
//given
UnusedStubbings stubbings = new UnusedStubbings((List) asList(
new StubbedInvocationMatcher(new InvocationBuilder().toInvocationMatcher(), new DoesNothing()),
new StubbedInvocationMatcher(new InvocationBuilder().toInvocationMatcher(), new DoesNothing())
new StubbedInvocationMatcher(new InvocationBuilder().toInvocationMatcher(), doesNothing()),
new StubbedInvocationMatcher(new InvocationBuilder().toInvocationMatcher(), doesNothing())
));


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,59 @@
*/
package org.mockito.internal.stubbing.answers;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.internal.stubbing.answers.DoesNothing.doesNothing;
import static org.mockitoutil.TestBase.getLastInvocation;

import org.junit.Before;
import org.junit.Test;
import org.mockito.exceptions.base.MockitoException;
import org.mockito.internal.invocation.InvocationBuilder;
import org.mockito.invocation.Invocation;
import org.mockitousage.IMethods;

import static org.assertj.core.api.Assertions.assertThat;
public class DoesNothingTest {

private IMethods mock;
private Invocation invocation_Void;
private Invocation invocation_void;
private Invocation invocation_String;

public class DoesNothingTest {
@Before
public void init(){
mock = mock(IMethods.class);

mock.voidMethod();
invocation_Void = getLastInvocation();

mock.voidReturningMethod();
invocation_void = getLastInvocation();

mock.simpleMethod();
invocation_String = getLastInvocation();
}

@Test
public void should_do_nothing() throws Throwable {
assertThat(new DoesNothing().answer(new InvocationBuilder().method("voidMethod").toInvocation())).isNull();
public void answer_returnsNull() throws Throwable {
assertThat(doesNothing().answer(invocation_Void)).isNull();
assertThat(doesNothing().answer(invocation_void)).isNull();
assertThat(doesNothing().answer(invocation_String)).isNull();
}

@Test(expected = MockitoException.class)
public void should_fail_when_non_void_method_does_nothing() throws Throwable {
new DoesNothing().validateFor(new InvocationBuilder().simpleMethod().toInvocation());
public void validateFor_nonVoidReturnType_shouldFail() {
doesNothing().validateFor(invocation_String);
}

@Test
public void should_allow_void_return_for_void_method() throws Throwable {
new DoesNothing().validateFor(new InvocationBuilder().method("voidMethod").toInvocation());
public void validateFor_voidReturnType_shouldPass() {
doesNothing().validateFor(invocation_void);
}

@Test
public void validateFor_voidObjectReturnType() throws Throwable {
doesNothing().validateFor(invocation_Void);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,17 @@
import java.lang.reflect.Method;
import java.nio.charset.CharacterCodingException;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.internal.invocation.InvocationBuilder;
import org.mockito.invocation.Invocation;
import org.mockitousage.IMethods;
import org.mockitoutil.TestBase;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockitoutil.TestBase.getLastInvocation;

public class InvocationInfoTest {

Expand Down Expand Up @@ -69,13 +76,41 @@ public void should_know_method_is_declared_on_interface() throws Exception {
assertThat(new InvocationInfo(new InvocationBuilder().method(iAmAbstract()).toInvocation()).isDeclaredOnInterface()).isFalse();
assertThat(new InvocationInfo(new InvocationBuilder().method("voidMethod").toInvocation()).isDeclaredOnInterface()).isTrue();
}

@Test
public void isVoid_invocationOnVoidMethod_returnTrue(){
mock(IMethods.class).voidMethod();

InvocationInfo voidMethod = new InvocationInfo(getLastInvocation());

assertThat(voidMethod.isVoid()).isTrue();
}

@Test
public void isVoid_invocationOnVoidReturningMethod_returnTrue(){
mock(IMethods.class).voidReturningMethod();

InvocationInfo voidRetuningMethod = new InvocationInfo(getLastInvocation());

assertThat(voidRetuningMethod.isVoid()).isTrue();
}

@Test
public void isVoid_invocationNonVoidMethod_returnFalse(){
mock(IMethods.class).simpleMethod();

InvocationInfo stringReturningMethod = new InvocationInfo(getLastInvocation());

assertThat(stringReturningMethod.isVoid()).isFalse();
}

private Method iAmAbstract() throws NoSuchMethodException {
abstract class TheAbstract {
abstract void iAmAbstract();
}
return TheAbstract.class.getDeclaredMethod("iAmAbstract");
}

private Method iAmNotAbstract() throws NoSuchMethodException {
abstract class TheNotAbstract {
void iAmNotAbstract() {};
Expand Down
2 changes: 2 additions & 0 deletions src/test/java/org/mockitousage/IMethods.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ public interface IMethods {
String toString(String foo);

void voidMethod();

Void voidReturningMethod();

String forList(List<String> list);

Expand Down
5 changes: 5 additions & 0 deletions src/test/java/org/mockitousage/MethodsImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -446,4 +446,9 @@ public Integer toIntWrapper(int i) {
public String forObject(Object object) {
return null;
}

@Override
public Void voidReturningMethod() {
return null;
}
}
2 changes: 1 addition & 1 deletion src/test/java/org/mockitoutil/TestBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public void resetState() {
new StateMaster().reset();
}

protected Invocation getLastInvocation() {
public static Invocation getLastInvocation() {
return new MockitoCore().getLastInvocation();
}

Expand Down

0 comments on commit 275586e

Please sign in to comment.