Skip to content

Instantly share code, notes, and snippets.

@stijnvanbael
Created July 10, 2013 11:50
Show Gist options
  • Save stijnvanbael/5965644 to your computer and use it in GitHub Desktop.
Save stijnvanbael/5965644 to your computer and use it in GitHub Desktop.
Provides a way to obtain an OngoingStubbing for Mockito spies or void methods. This allows you to write highly readable code in your tests.
import org.mockito.Mockito;
import org.mockito.internal.stubbing.answers.ThrowsException;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.mockito.stubbing.OngoingStubbing;
import org.mockito.stubbing.Stubber;
/**
* <p>
* Provides a way to obtain an OngoingStubbing for spies or void methods. This allows you to write highly readable code in your tests.
* </p>
*
* <p>
* Example:
* </p>
*
* <pre>
* {@code
* &#064;Spy
* private Radio radio = new Radio();
*
* &#064;Test
* public void carShouldStillStartWhenRadioThrowsException() {
* whenTurningOnRadio(radio).thenThrow(new Exception());
* Car car = new Car();
* car.add(radio);
* car.start();
* assertTrue(car.isRunning());
* }
*
* private OngoingStubbing&lt;Void&gt; whenTurningOnRadio(Radio radio) {
* return new OngoingStubbingAdapter&lt;Void&gt;() {
* &#064;Override
* protected void withStubber(Stubber doStub) {
* doStub.when(radio).turnOn();
* }
* };
* }
* }
* </pre>
*/
public abstract class OngoingStubbingAdapter<T> implements OngoingStubbing<T> {
protected abstract void withStubber(Stubber doStub);
@Override
public OngoingStubbing<T> thenReturn(T value) {
withStubber(Mockito.doReturn(value));
return this;
}
@Override
public OngoingStubbing<T> thenReturn(final T value, final T... values) {
withStubber(Mockito.doAnswer(new Answer<T>() {
private int count = 0;
@Override
public T answer(InvocationOnMock invocation) throws Throwable {
if (count == 0) {
return value;
}
if (count >= values.length) {
return values[values.length - 1];
}
count++;
return values[count - 2];
}
}));
return this;
}
@Override
public OngoingStubbing<T> thenThrow(final Throwable... throwables) {
withStubber(Mockito.doAnswer(new Answer<T>() {
private int count = 0;
@Override
public T answer(InvocationOnMock invocation) throws Throwable {
if (throwables.length > 0) {
Throwable throwable;
if (count > throwables.length) {
throwable = throwables[throwables.length - 1];
} else {
throwable = throwables[count];
count++;
}
new ThrowsException(throwable).answer(invocation);
}
return null;
}
}));
return this;
}
@Override
public OngoingStubbing<T> thenCallRealMethod() {
withStubber(Mockito.doCallRealMethod());
return this;
}
@Override
public OngoingStubbing<T> thenAnswer(Answer<?> answer) {
withStubber(Mockito.doAnswer(answer));
return this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment