/* * 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()); } }