blob: ef478a108202ee6f0d942e9f496e070068a16217 [file] [log] [blame]
/*
* Copyright (c) 2007 Mockito contributors
* This program is made available under the terms of the MIT License.
*/
package org.mockito;
import org.mockito.stubbing.Answer;
import org.mockito.stubbing.OngoingStubbing;
import org.mockito.stubbing.Stubber;
import org.mockito.verification.VerificationMode;
/**
* Behavior Driven Development style of writing tests uses <b>//given //when //then</b> comments as fundamental parts of your test methods.
* This is exactly how we write our tests and we warmly encourage you to do so!
* <p>
* Start learning about BDD here: <a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development">http://en.wikipedia.org/wiki/Behavior_Driven_Development</a>
* <p>
* The problem is that current stubbing api with canonical role of <b>when</b> word does not integrate nicely with <b>//given //when //then</b> comments.
* It's because stubbing belongs to <b>given</b> component of the test and not to the <b>when</b> component of the test.
* Hence {@link BDDMockito} class introduces an alias so that you stub method calls with {@link BDDMockito#given(Object)} method.
* Now it really nicely integrates with the <b>given</b> component of a BDD style test!
* <p>
* Here is how the test might look like:
* <pre class="code"><code class="java">
* import static org.mockito.BDDMockito.*;
*
* Seller seller = mock(Seller.class);
* Shop shop = new Shop(seller);
*
* public void shouldBuyBread() throws Exception {
* //given
* given(seller.askForBread()).willReturn(new Bread());
*
* //when
* Goods goods = shop.buyBread();
*
* //then
* assertThat(goods, containBread());
* }
* </code></pre>
*
* Stubbing voids with throwables:
* <pre class="code"><code class="java">
* //given
* willThrow(new RuntimeException("boo")).given(mock).foo();
*
* //when
* Result result = systemUnderTest.perform();
*
* //then
* assertEquals(failure, result);
* </code></pre>
* <p>
* For BDD style mock verification take a look at {@link Then} in action:
* <pre class="code"><code class="java">
* person.ride(bike);
* person.ride(bike);
*
* then(person).should(times(2)).ride(bike);
* then(person).shouldHaveNoMoreInteractions();
* then(police).shouldHaveZeroInteractions();
* </code></pre>
* <p>
* It is also possible to do BDD style {@link InOrder} verification:
* <pre class="code"><code class="java">
* InOrder inOrder = inOrder(person);
*
* person.drive(car);
* person.ride(bike);
* person.ride(bike);
*
* then(person).should(inOrder).drive(car);
* then(person).should(inOrder, times(2)).ride(bike);
* </code></pre>
* <p>
* One of the purposes of BDDMockito is also to show how to tailor the mocking syntax to a different programming style.
*
* @since 1.8.0
*/
@SuppressWarnings("unchecked")
public class BDDMockito extends Mockito {
/**
* See original {@link OngoingStubbing}
* @since 1.8.0
*/
public interface BDDMyOngoingStubbing<T> {
/**
* See original {@link OngoingStubbing#thenAnswer(Answer)}
* @since 1.8.0
*/
BDDMyOngoingStubbing<T> willAnswer(Answer<?> answer);
/**
* See original {@link OngoingStubbing#then(Answer)}
* @since 1.9.0
*/
BDDMyOngoingStubbing<T> will(Answer<?> answer);
/**
* See original {@link OngoingStubbing#thenReturn(Object)}
* @since 1.8.0
*/
BDDMyOngoingStubbing<T> willReturn(T value);
/**
* See original {@link OngoingStubbing#thenReturn(Object, Object[])}
* @since 1.8.0
*/
@SuppressWarnings({"unchecked", "varargs"})
BDDMyOngoingStubbing<T> willReturn(T value, T... values);
/**
* See original {@link OngoingStubbing#thenThrow(Throwable...)}
* @since 1.8.0
*/
BDDMyOngoingStubbing<T> willThrow(Throwable... throwables);
/**
* See original {@link OngoingStubbing#thenThrow(Class)}
* @since 2.1.0
*/
BDDMyOngoingStubbing<T> willThrow(Class<? extends Throwable> throwableType);
/**
* See original {@link OngoingStubbing#thenThrow(Class, Class[])}
* @since 2.1.0
*/
// Additional method helps users of JDK7+ to hide heap pollution / unchecked generics array creation
@SuppressWarnings ({"unchecked", "varargs"})
BDDMyOngoingStubbing<T> willThrow(Class<? extends Throwable> throwableType, Class<? extends Throwable>... throwableTypes);
/**
* See original {@link OngoingStubbing#thenCallRealMethod()}
* @since 1.9.0
*/
BDDMyOngoingStubbing<T> willCallRealMethod();
/**
* See original {@link OngoingStubbing#getMock()}
* @since 1.9.0
*/
<M> M getMock();
}
private static class BDDOngoingStubbingImpl<T> implements BDDMyOngoingStubbing<T> {
private final OngoingStubbing<T> mockitoOngoingStubbing;
public BDDOngoingStubbingImpl(OngoingStubbing<T> ongoingStubbing) {
this.mockitoOngoingStubbing = ongoingStubbing;
}
public BDDMyOngoingStubbing<T> willAnswer(Answer<?> answer) {
return new BDDOngoingStubbingImpl<T>(mockitoOngoingStubbing.thenAnswer(answer));
}
public BDDMyOngoingStubbing<T> will(Answer<?> answer) {
return new BDDOngoingStubbingImpl<T>(mockitoOngoingStubbing.then(answer));
}
public BDDMyOngoingStubbing<T> willReturn(T value) {
return new BDDOngoingStubbingImpl<T>(mockitoOngoingStubbing.thenReturn(value));
}
public BDDMyOngoingStubbing<T> willReturn(T value, T... values) {
return new BDDOngoingStubbingImpl<T>(mockitoOngoingStubbing.thenReturn(value, values));
}
public BDDMyOngoingStubbing<T> willThrow(Throwable... throwables) {
return new BDDOngoingStubbingImpl<T>(mockitoOngoingStubbing.thenThrow(throwables));
}
public BDDMyOngoingStubbing<T> willThrow(Class<? extends Throwable> throwableType) {
return new BDDOngoingStubbingImpl<T>(mockitoOngoingStubbing.thenThrow(throwableType));
}
public BDDMyOngoingStubbing<T> willThrow(Class<? extends Throwable> throwableType, Class<? extends Throwable>... throwableTypes) {
return new BDDOngoingStubbingImpl<T>(mockitoOngoingStubbing.thenThrow(throwableType, throwableTypes));
}
public BDDMyOngoingStubbing<T> willCallRealMethod() {
return new BDDOngoingStubbingImpl<T>(mockitoOngoingStubbing.thenCallRealMethod());
}
public <M> M getMock() {
return (M) mockitoOngoingStubbing.getMock();
}
}
/**
* see original {@link Mockito#when(Object)}
* @since 1.8.0
*/
public static <T> BDDMyOngoingStubbing<T> given(T methodCall) {
return new BDDOngoingStubbingImpl<T>(Mockito.when(methodCall));
}
/**
* Bdd style verification of mock behavior.
*
* <pre class="code"><code class="java">
* person.ride(bike);
* person.ride(bike);
*
* then(person).should(times(2)).ride(bike);
* </code></pre>
*
* @see #verify(Object)
* @see #verify(Object, VerificationMode)
* @since 1.10.0
*/
public static <T> Then<T> then(T mock) {
return new ThenImpl<T>(mock);
}
/**
* Provides fluent way of mock verification.
*
* @param <T> type of the mock
*
* @since 1.10.5
*/
public interface Then<T> {
/**
* @see #verify(Object)
* @since 1.10.5
*/
T should();
/**
* @see #verify(Object, VerificationMode)
* @since 1.10.5
*/
T should(VerificationMode mode);
/**
* @see InOrder#verify(Object)
* @since 2.1.0
*/
T should(InOrder inOrder);
/**
* @see InOrder#verify(Object, VerificationMode)
* @since 2.1.0
*/
T should(InOrder inOrder, VerificationMode mode);
/**
* @see #verifyZeroInteractions(Object...)
* @since 2.1.0
*/
void shouldHaveZeroInteractions();
/**
* @see #verifyNoMoreInteractions(Object...)
* @since 2.1.0
*/
void shouldHaveNoMoreInteractions();
/**
* @see #verifyNoInteractions(Object...)
* @since 3.0.0
*/
void shouldHaveNoInteractions();
}
private static class ThenImpl<T> implements Then<T> {
private final T mock;
ThenImpl(T mock) {
this.mock = mock;
}
/**
* @see #verify(Object)
* @since 1.10.5
*/
public T should() {
return verify(mock);
}
/**
* @see #verify(Object, VerificationMode)
* @since 1.10.5
*/
public T should(VerificationMode mode) {
return verify(mock, mode);
}
/**
* @see InOrder#verify(Object)
* @since 2.1.0
*/
public T should(InOrder inOrder) {
return inOrder.verify(mock);
}
/**
* @see InOrder#verify(Object, VerificationMode)
* @since 2.1.0
*/
public T should(InOrder inOrder, VerificationMode mode) {
return inOrder.verify(mock, mode);
}
/**
* @see #verifyZeroInteractions(Object...)
* @since 2.1.0
* @deprecated Since 3.0.0. Please migrate your code to {@link #shouldHaveNoInteractions()}
*/
@Deprecated
public void shouldHaveZeroInteractions() {
verifyZeroInteractions(mock);
}
/**
* @see #verifyNoInteractions(Object...)
* @since 3.0.0
*/
public void shouldHaveNoInteractions() {
verifyNoInteractions(mock);
}
/**
* @see #verifyNoMoreInteractions(Object...)
* @since 2.1.0
*/
public void shouldHaveNoMoreInteractions() {
verifyNoMoreInteractions(mock);
}
}
/**
* See original {@link Stubber}
* @since 1.8.0
*/
public interface BDDStubber {
/**
* See original {@link Stubber#doAnswer(Answer)}
* @since 1.8.0
*/
BDDStubber willAnswer(Answer<?> answer);
/**
* See original {@link Stubber#doAnswer(Answer)}
* @since 1.8.0
*/
BDDStubber will(Answer<?> answer);
/**
* See original {@link Stubber#doNothing()}.
*
* This method will be removed in version 3.0.0
*
* @since 1.8.0
* @deprecated as of 2.1.0 please use {@link #willDoNothing()} instead
*/
@Deprecated
BDDStubber willNothing();
/**
* See original {@link Stubber#doNothing()}
* @since 1.10.20
*/
BDDStubber willDoNothing();
/**
* See original {@link Stubber#doReturn(Object)}
* @since 2.1.0
*/
BDDStubber willReturn(Object toBeReturned);
/**
* See original {@link Stubber#doReturn(Object)}
* @since 2.1.0
*/
@SuppressWarnings({"unchecked", "varargs"})
BDDStubber willReturn(Object toBeReturned, Object... nextToBeReturned);
/**
* See original {@link Stubber#doThrow(Throwable...)}
* @since 1.8.0
*/
BDDStubber willThrow(Throwable... toBeThrown);
/**
* See original {@link Stubber#doThrow(Class)}
* @since 2.1.0
*/
BDDStubber willThrow(Class<? extends Throwable> toBeThrown);
/**
* See original {@link Stubber#doThrow(Class, Class[])}
* @since 2.1.0
*/
@SuppressWarnings ({"unchecked", "varargs"})
BDDStubber willThrow(Class<? extends Throwable> toBeThrown, Class<? extends Throwable>... nextToBeThrown);
/**
* See original {@link Stubber#doCallRealMethod()}
* @since 1.9.0
*/
BDDStubber willCallRealMethod();
/**
* See original {@link Stubber#when(Object)}
* @since 1.8.0
*/
<T> T given(T mock);
}
private static class BDDStubberImpl implements BDDStubber {
private final Stubber mockitoStubber;
public BDDStubberImpl(Stubber mockitoStubber) {
this.mockitoStubber = mockitoStubber;
}
public <T> T given(T mock) {
return mockitoStubber.when(mock);
}
public BDDStubber willAnswer(Answer<?> answer) {
return new BDDStubberImpl(mockitoStubber.doAnswer(answer));
}
public BDDStubber will(Answer<?> answer) {
return new BDDStubberImpl(mockitoStubber.doAnswer(answer));
}
/**
* @deprecated please use {@link #willDoNothing()} instead
*/
@Deprecated
public BDDStubber willNothing() {
return willDoNothing();
}
public BDDStubber willDoNothing() {
return new BDDStubberImpl(mockitoStubber.doNothing());
}
public BDDStubber willReturn(Object toBeReturned) {
return new BDDStubberImpl(mockitoStubber.doReturn(toBeReturned));
}
public BDDStubber willReturn(Object toBeReturned, Object... nextToBeReturned) {
return new BDDStubberImpl(mockitoStubber.doReturn(toBeReturned).doReturn(nextToBeReturned));
}
public BDDStubber willThrow(Throwable... toBeThrown) {
return new BDDStubberImpl(mockitoStubber.doThrow(toBeThrown));
}
public BDDStubber willThrow(Class<? extends Throwable> toBeThrown) {
return new BDDStubberImpl(mockitoStubber.doThrow(toBeThrown));
}
public BDDStubber willThrow(Class<? extends Throwable> toBeThrown, Class<? extends Throwable>... nextToBeThrown) {
return new BDDStubberImpl(mockitoStubber.doThrow(toBeThrown, nextToBeThrown));
}
public BDDStubber willCallRealMethod() {
return new BDDStubberImpl(mockitoStubber.doCallRealMethod());
}
}
/**
* see original {@link Mockito#doThrow(Throwable[])}
* @since 2.1.0
*/
public static BDDStubber willThrow(Throwable... toBeThrown) {
return new BDDStubberImpl(Mockito.doThrow(toBeThrown));
}
/**
* see original {@link Mockito#doThrow(Class)}
* @since 1.9.0
*/
public static BDDStubber willThrow(Class<? extends Throwable> toBeThrown) {
return new BDDStubberImpl(Mockito.doThrow(toBeThrown));
}
/**
* see original {@link Mockito#doThrow(Class)}
* @since 1.9.0
*/
public static BDDStubber willThrow(Class<? extends Throwable> toBeThrown, Class<? extends Throwable>... throwableTypes) {
return new BDDStubberImpl(Mockito.doThrow(toBeThrown, throwableTypes));
}
/**
* see original {@link Mockito#doAnswer(Answer)}
* @since 1.8.0
*/
public static BDDStubber willAnswer(Answer<?> answer) {
return new BDDStubberImpl(Mockito.doAnswer(answer));
}
/**
* see original {@link Mockito#doAnswer(Answer)}
* @since 2.1.0
*/
public static BDDStubber will(Answer<?> answer) {
return new BDDStubberImpl(Mockito.doAnswer(answer));
}
/**
* see original {@link Mockito#doNothing()}
* @since 1.8.0
*/
public static BDDStubber willDoNothing() {
return new BDDStubberImpl(Mockito.doNothing());
}
/**
* see original {@link Mockito#doReturn(Object)}
* @since 1.8.0
*/
public static BDDStubber willReturn(Object toBeReturned) {
return new BDDStubberImpl(Mockito.doReturn(toBeReturned));
}
/**
* see original {@link Mockito#doReturn(Object, Object...)}
* @since 2.1.0
*/
@SuppressWarnings({"unchecked", "varargs"})
public static BDDStubber willReturn(Object toBeReturned, Object... toBeReturnedNext) {
return new BDDStubberImpl(Mockito.doReturn(toBeReturned, toBeReturnedNext));
}
/**
* see original {@link Mockito#doCallRealMethod()}
* @since 1.8.0
*/
public static BDDStubber willCallRealMethod() {
return new BDDStubberImpl(Mockito.doCallRealMethod());
}
}