org.powermock.api.mockito.PowerMockito Maven / Gradle / Ivy
Show all versions of powermock-api-mockito2 Show documentation
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.powermock.api.mockito;
import org.mockito.MockSettings;
import org.mockito.Mockito;
import org.mockito.internal.progress.ThreadSafeMockingProgress;
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.stubbing.Answer;
import org.mockito.stubbing.OngoingStubbing;
import org.mockito.verification.VerificationMode;
import org.powermock.api.mockito.expectation.ConstructorExpectationSetup;
import org.powermock.api.mockito.expectation.PowerMockitoStubber;
import org.powermock.api.mockito.expectation.WithOrWithoutExpectedArguments;
import org.powermock.api.mockito.internal.PowerMockitoCore;
import org.powermock.api.mockito.internal.expectation.ConstructorAwareExpectationSetup;
import org.powermock.api.mockito.internal.expectation.DefaultConstructorExpectationSetup;
import org.powermock.api.mockito.internal.expectation.DefaultMethodExpectationSetup;
import org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator;
import org.powermock.api.mockito.internal.stubbing.answers.ChainReturns;
import org.powermock.api.mockito.internal.verification.DefaultConstructorArgumentsVerfication;
import org.powermock.api.mockito.internal.verification.DefaultPrivateMethodVerification;
import org.powermock.api.mockito.internal.verification.VerifyNoMoreInteractions;
import org.powermock.api.mockito.verification.ConstructorArgumentsVerification;
import org.powermock.api.mockito.verification.PrivateMethodVerification;
import org.powermock.api.support.membermodification.MemberModifier;
import org.powermock.core.MockRepository;
import org.powermock.core.spi.NewInvocationControl;
import org.powermock.reflect.Whitebox;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.withSettings;
/**
* PowerMockito extends Mockito functionality with several new features such as
* mocking static and private methods and more. Use PowerMock instead of Mockito
* where applicable.
*
* @see Mockito
*/
public class PowerMockito extends MemberModifier {
private static final String NO_OBJECT_CREATION_ERROR_MESSAGE_TEMPLATE = "No instantiation of class %s was recorded during the test. Note that only expected object creations (e.g. those using whenNew(..)) can be verified.";
private static final PowerMockitoCore POWERMOCKITO_CORE = new PowerMockitoCore();
/**
* Enable static mocking for all methods of a class.
*
* @param type the class to enable static mocking
*/
public static synchronized void mockStatic(Class> type, Class>... types) {
ThreadSafeMockingProgress.mockingProgress().reset();
DefaultMockCreator.mock(type, true, false, null, null, (Method[]) null);
if (types != null && types.length > 0) {
for (Class> aClass : types) {
DefaultMockCreator.mock(aClass, true, false, null, null, (Method[]) null);
}
}
}
/**
* Creates class mock with a specified strategy for its answers to
* interactions. It's quite advanced feature and typically you don't need it
* to write decent tests. However it can be helpful when working with legacy
* systems.
*
* It is the default answer so it will be used only when you don't
* stub the method call.
*
*
* mockStatic(Foo.class, RETURNS_SMART_NULLS);
* mockStatic(Foo.class, new YourOwnAnswer());
*
*
* @param classMock class to mock
* @param defaultAnswer default answer for unstubbed methods
*/
public static void mockStatic(Class> classMock, @SuppressWarnings("rawtypes") Answer defaultAnswer) {
mockStatic(classMock, withSettings().defaultAnswer(defaultAnswer));
}
/**
* Creates a class mock with some non-standard settings.
*
* The number of configuration points for a mock grows so we need a fluent
* way to introduce new configuration without adding more and more
* overloaded PowerMockito.mockStatic() methods. Hence {@link MockSettings}.
*
*
* mockStatic(Listener.class, withSettings()
* .name("firstListner").defaultBehavior(RETURNS_SMART_NULLS));
* );
*
*
* Use it carefully and occasionally. What might be reason your test
* needs non-standard mocks? Is the code under test so complicated that it
* requires non-standard mocks? Wouldn't you prefer to refactor the code
* under test so it is testable in a simple way?
*
* See also {@link Mockito#withSettings()}
*
* @param classToMock class to mock
* @param mockSettings additional mock settings
*/
public static void mockStatic(Class> classToMock, MockSettings mockSettings) {
ThreadSafeMockingProgress.mockingProgress().reset();
DefaultMockCreator.mock(classToMock, true, false, null, mockSettings, (Method[]) null);
}
/**
* Creates a mock object that supports mocking of final and native methods.
*
* @param the type of the mock object
* @param type the type of the mock object
* @return the mock object.
*/
public static synchronized T mock(Class type) {
return DefaultMockCreator.mock(type, false, false, null, null, (Method[]) null);
}
/**
* Creates mock with a specified strategy for its answers to interactions.
* It's quite advanced feature and typically you don't need it to write
* decent tests. However it can be helpful when working with legacy systems.
*
* It is the default answer so it will be used only when you don't
* stub the method call.
*
*
* Foo mock = mock(Foo.class, RETURNS_SMART_NULLS);
* Foo mockTwo = mock(Foo.class, new YourOwnAnswer());
*
*
*
* See examples in javadoc for {@link Mockito} class
*
*
* @param classToMock class or interface to mock
* @param defaultAnswer default answer for unstubbed methods
* @return mock object
*/
public static T mock(Class classToMock, @SuppressWarnings("rawtypes") Answer defaultAnswer) {
return mock(classToMock, withSettings().defaultAnswer(defaultAnswer));
}
/**
* Creates a mock with some non-standard settings.
*
* The number of configuration points for a mock grows so we need a fluent
* way to introduce new configuration without adding more and more
* overloaded Mockito.mock() methods. Hence {@link MockSettings}.
*
*
* Listener mock = mock(Listener.class, withSettings()
* .name("firstListner").defaultBehavior(RETURNS_SMART_NULLS));
* );
*
*
* Use it carefully and occasionally. What might be reason your test
* needs non-standard mocks? Is the code under test so complicated that it
* requires non-standard mocks? Wouldn't you prefer to refactor the code
* under test so it is testable in a simple way?
*
* See also {@link Mockito#withSettings()}
*
* See examples in javadoc for {@link Mockito} class
*
* @param classToMock class or interface to mock
* @param mockSettings additional mock settings
* @return mock object
*/
public static T mock(Class classToMock, MockSettings mockSettings) {
return DefaultMockCreator.mock(classToMock, false, false, null, mockSettings, (Method[]) null);
}
/**
* Spy on objects that are final or otherwise not "spyable" from
* normal Mockito.
*
* @param the type of the mock object
* @param object the object to spy on
* @return the spy object.
* @see Mockito#spy(Object)
*/
@SuppressWarnings("unchecked")
public static synchronized T spy(T object) {
return DefaultMockCreator.mock((Class) Whitebox.getType(object), false, true, object, null, (Method[]) null);
}
/**
* Spy on classes (not "spyable" from normal Mockito).
*
* @param the type of the class mock
* @param type the type of the class mock
* @see Mockito#spy(Object)
*/
public static synchronized void spy(Class type) {
ThreadSafeMockingProgress.mockingProgress().reset();
DefaultMockCreator.mock(type, true, true, type, null, (Method[]) null);
}
/**
* Verifies certain behavior happened once
*
* Alias to verifyStatic(times(1))
E.g:
*
*
* verifyStatic();
* ClassWithStaticMethod.someStaticMethod("some arg");
*
*
* Above is equivalent to:
*
*
* verifyStatic(times(1));
* ClassWithStaticMethod.someStaticMethod("some arg");
*
*
*
* Although it is possible to verify a stubbed invocation, usually it's
* just redundant. Let's say you've stubbed foo.bar(). If your code
* cares what foo.bar() returns then something else breaks(often before even
* verify() gets executed). If your code doesn't care what get(0) returns
* then it should not be stubbed.
*/
public static synchronized void verifyStatic() {
verifyStatic(times(1));
}
/**
* Verifies certain behavior happened at least once / exact number of times
* / never. E.g:
*
*
* verifyStatic(times(5));
* ClassWithStaticMethod.someStaticMethod("was called five times");
*
* verifyStatic(atLeast(2));
* ClassWithStaticMethod.someStaticMethod("was called at least two times");
*
* //you can use flexible argument matchers, e.g:
* verifyStatic(atLeastOnce());
* ClassWithStaticMethod.someMethod(<b>anyString()</b>);
*
*
* times(1) is the default and can be omitted
*
*
* @param verificationMode times(x), atLeastOnce() or never()
*/
public static synchronized void verifyStatic(VerificationMode verificationMode) {
ThreadSafeMockingProgress.mockingProgress().verificationStarted(
POWERMOCKITO_CORE.wrapInStaticVerificationMode(verificationMode));
}
/**
* Verify a private method invocation for an instance.
*
* @throws Exception If something unexpected goes wrong.
* @see {@link Mockito#verify(Object)}
*/
public static PrivateMethodVerification verifyPrivate(Object object) throws Exception {
return verifyPrivate(object, times(1));
}
/**
* Verify a private method invocation with a given verification mode.
*
* @throws Exception If something unexpected goes wrong.
* @see {@link Mockito#verify(Object)}
*/
public static PrivateMethodVerification verifyPrivate(Object object, VerificationMode verificationMode)
throws Exception {
ThreadSafeMockingProgress.mockingProgress().verificationStarted(
POWERMOCKITO_CORE.wrapInMockitoSpecificVerificationMode(object, verificationMode));
return new DefaultPrivateMethodVerification(object);
}
/**
* Verify a private method invocation for a class.
*
* @throws Exception If something unexpected goes wrong.
* @see {@link Mockito#verify(Object)}
*/
public static PrivateMethodVerification verifyPrivate(Class> clazz) throws Exception {
return verifyPrivate((Object) clazz);
}
/**
* Verify a private method invocation for a class with a given verification
* mode.
*
* @throws Exception If something unexpected goes wrong.
* @see {@link Mockito#verify(Object)}
*/
public static PrivateMethodVerification verifyPrivate(Class> clazz, VerificationMode verificationMode)
throws Exception {
return verifyPrivate((Object) clazz, verificationMode);
}
/**
* Verifies certain behavior happened once
*
* Alias to verifyNew(mockClass, times(1))
E.g:
*
*
* verifyNew(ClassWithStaticMethod.class);
*
*
* Above is equivalent to:
*
*
* verifyNew(ClassWithStaticMethod.class, times(1));
*
*
*
*
* @param mock Class mocked by PowerMock.
*/
@SuppressWarnings("unchecked")
public static synchronized ConstructorArgumentsVerification verifyNew(Class mock) {
if (mock == null) {
throw new IllegalArgumentException("Class to verify cannot be null");
}
NewInvocationControl> invocationControl = MockRepository.getNewInstanceControl(mock);
if (invocationControl == null) {
throw new IllegalStateException(String.format(NO_OBJECT_CREATION_ERROR_MESSAGE_TEMPLATE, Whitebox.getType(
mock).getName()));
}
invocationControl.verify();
return new DefaultConstructorArgumentsVerfication((NewInvocationControl) invocationControl, mock);
}
/**
* Verifies certain behavior happened at least once / exact number of times
* / never. E.g:
*
*
* verifyNew(ClassWithStaticMethod.class, times(5));
*
* verifyNew(ClassWithStaticMethod.class, atLeast(2));
*
* //you can use flexible argument matchers, e.g:
* verifyNew(ClassWithStaticMethod.class, atLeastOnce());
*
*
* times(1) is the default and can be omitted
*
*
* @param mock to be verified
* @param mode times(x), atLeastOnce() or never()
*/
@SuppressWarnings("unchecked")
public static ConstructorArgumentsVerification verifyNew(Class> mock, VerificationMode mode) {
if (mock == null) {
throw new IllegalArgumentException("Class to verify cannot be null");
} else if (mode == null) {
throw new IllegalArgumentException("Verify mode cannot be null");
}
NewInvocationControl> invocationControl = MockRepository.getNewInstanceControl(mock);
MockRepository.putAdditionalState("VerificationMode", POWERMOCKITO_CORE.wrapInMockitoSpecificVerificationMode(
mock, mode));
if (invocationControl == null) {
throw new IllegalStateException(String.format(NO_OBJECT_CREATION_ERROR_MESSAGE_TEMPLATE, Whitebox.getType(
mock).getName()));
}
try {
invocationControl.verify();
} finally {
MockRepository.removeAdditionalState("VerificationMode");
}
return new DefaultConstructorArgumentsVerfication((NewInvocationControl) invocationControl, mock);
}
/**
* Expect calls to private methods.
*
* @throws Exception If something unexpected goes wrong.
* @see {@link Mockito#when(Object)}
*/
public static OngoingStubbing when(Object instance, String methodName, Object... arguments) throws Exception {
return Mockito.when(Whitebox.invokeMethod(instance, methodName, arguments));
}
/**
* Expect calls to private methods.
*
* @throws Exception If something unexpected goes wrong.
* @see {@link Mockito#when(Object)}
*/
public static WithOrWithoutExpectedArguments when(Object instance, Method method) throws Exception {
return new DefaultMethodExpectationSetup(instance, method);
}
/**
* Expect calls to private static methods.
*
* @throws Exception If something unexpected goes wrong.
* @see {@link Mockito#when(Object)}
*/
public static WithOrWithoutExpectedArguments when(Class> cls, Method method) throws Exception {
return new DefaultMethodExpectationSetup(cls, method);
}
/**
* Expect calls to private methods without having to specify the method
* name. The method will be looked up using the parameter types (if
* possible).
*
* @throws Exception If something unexpected goes wrong.
* @see {@link Mockito#when(Object)}
*/
public static OngoingStubbing when(Object instance, Object... arguments) throws Exception {
return Mockito.when(Whitebox.invokeMethod(instance, arguments));
}
/**
* Expect a static private or inner class method call.
*
* @throws Exception If something unexpected goes wrong.
* @see {@link Mockito#when(Object)}
*/
public static OngoingStubbing when(Class> clazz, String methodToExpect, Object... arguments)
throws Exception {
return Mockito.when(Whitebox.invokeMethod(clazz, methodToExpect, arguments));
}
/**
* Expect calls to private static methods without having to specify the
* method name. The method will be looked up using the parameter types if
* possible
*
* @throws Exception If something unexpected goes wrong.
* @see {@link Mockito#when(Object)}
*/
public static OngoingStubbing when(Class> klass, Object... arguments) throws Exception {
return Mockito.when(Whitebox.invokeMethod(klass, arguments));
}
/**
* Just delegates to the original {@link Mockito#when(Object)} method.
*
* @see {@link Mockito#when(Object)}
*/
public static OngoingStubbing when(T methodCall) {
return Mockito.when(methodCall);
}
/**
* Allows specifying expectations on new invocations. For example you might
* want to throw an exception or return a mock.
*/
public static synchronized WithOrWithoutExpectedArguments whenNew(Constructor ctor) {
return new ConstructorAwareExpectationSetup(ctor);
}
/**
* Allows specifying expectations on new invocations. For example you might
* want to throw an exception or return a mock.
*/
public static synchronized ConstructorExpectationSetup whenNew(Class type) {
return new DefaultConstructorExpectationSetup(type);
}
/**
* Allows specifying expectations on new invocations for private member
* (inner) classes, local or anonymous classes. For example you might want
* to throw an exception or return a mock.
*
* @param fullyQualifiedName The fully-qualified name of the inner/local/anonymous type to
* expect.
*/
@SuppressWarnings("unchecked")
public static synchronized ConstructorExpectationSetup whenNew(String fullyQualifiedName) throws Exception {
final Class forName = (Class) Class.forName(fullyQualifiedName);
return new DefaultConstructorExpectationSetup(forName);
}
/**
* Checks if any of given mocks (can be both instance and class mocks) has
* any unverified interaction. Delegates to the orignal
* {@link Mockito#verifyNoMoreInteractions(Object...)} if the mock is not a
* PowerMockito mock.
*
* You can use this method after you verified your mocks - to make sure that
* nothing else was invoked on your mocks.
*
* See also {@link Mockito#never()} - it is more explicit and communicates
* the intent well.
*
* Stubbed invocations (if called) are also treated as interactions.
*
* A word of warning: Some users who did a lot of classic,
* expect-run-verify mocking tend to use verifyNoMoreInteractions() very
* often, even in every test method. verifyNoMoreInteractions() is not
* recommended to use in every test method. verifyNoMoreInteractions() is a
* handy assertion from the interaction testing toolkit. Use it only when
* it's relevant. Abusing it leads to overspecified, less maintainable
* tests. You can find further reading here.
*
* This method will also detect unverified invocations that occurred before
* the test method, for example: in setUp(), @Before method or in
* constructor. Consider writing nice code that makes interactions only in
* test methods.
*
*
* Example:
*
*
* //interactions
* mock.doSomething();
* mock.doSomethingUnexpected();
*
* //verification
* verify(mock).doSomething();
*
* //following will fail because 'doSomethingUnexpected()' is unexpected
* verifyNoMoreInteractions(mock);
*
*
*
* See examples in javadoc for {@link Mockito} class
*
* @param mocks to be verified
*/
public static void verifyNoMoreInteractions(Object... mocks) {
VerifyNoMoreInteractions.verifyNoMoreInteractions(mocks);
}
/**
* Verifies that no interactions happened on given mocks (can be both
* instance and class mocks). Delegates to the orignal
* {@link Mockito#verifyNoMoreInteractions(Object...)} if the mock is not a
* PowerMockito mock.
*
*
* verifyZeroInteractions(mockOne, mockTwo);
*
*
* This method will also detect invocations that occurred before the test
* method, for example: in setUp(), @Before method or in constructor.
* Consider writing nice code that makes interactions only in test methods.
*
* See also {@link Mockito#never()} - it is more explicit and communicates
* the intent well.
*
* See examples in javadoc for {@link Mockito} class
*
* @param mocks to be verified
*/
public static void verifyZeroInteractions(Object... mocks) {
VerifyNoMoreInteractions.verifyNoMoreInteractions(mocks);
}
/**
* Use doAnswer() when you want to stub a void method with generic
* {@link Answer}.
*
* Stubbing voids requires different approach from
* {@link Mockito#when(Object)} because the compiler does not like void
* methods inside brackets...
*
* Example:
*
*
* doAnswer(new Answer() {
* public Object answer(InvocationOnMock invocation) {
* Object[] args = invocation.getArguments();
* Mock mock = invocation.getMock();
* return null;
* }
* }).when(mock).someMethod();
*
*
* See examples in javadoc for {@link Mockito} class
*
* @param answer to answer when the stubbed method is called
* @return stubber - to select a method for stubbing
*/
public static PowerMockitoStubber doAnswer(Answer> answer) {
return POWERMOCKITO_CORE.doAnswer(answer);
}
/**
* Use doThrow() when you want to stub the void method with an exception.
*
* Stubbing voids requires different approach from
* {@link Mockito#when(Object)} because the compiler does not like void
* methods inside brackets...
*
* Example:
*
*
* doThrow(new RuntimeException()).when(mock).someVoidMethod();
*
*
* @param toBeThrown to be thrown when the stubbed method is called
* @return stubber - to select a method for stubbing
*/
public static PowerMockitoStubber doThrow(Throwable toBeThrown) {
return POWERMOCKITO_CORE.doAnswer(new ThrowsException(toBeThrown));
}
/**
* Use doCallRealMethod() when you want to call the real implementation of a
* method.
*
* As usual you are going to read the partial mock warning: Object
* oriented programming is more less tackling complexity by dividing the
* complexity into separate, specific, SRPy objects. How does partial mock
* fit into this paradigm? Well, it just doesn't... Partial mock usually
* means that the complexity has been moved to a different method on the
* same object. In most cases, this is not the way you want to design your
* application.
*
* However, there are rare cases when partial mocks come handy: dealing with
* code you cannot change easily (3rd party interfaces, interim refactoring
* of legacy code etc.) However, I wouldn't use partial mocks for new,
* test-driven & well-designed code.
*
* See also javadoc {@link Mockito#spy(Object)} to find out more about
* partial mocks. Mockito.spy() is a recommended way of creating partial
* mocks. The reason is it guarantees real methods are called against
* correctly constructed object because you're responsible for constructing
* the object passed to spy() method.
*
* Example:
*
*
* Foo mock = mock(Foo.class);
* doCallRealMethod().when(mock).someVoidMethod();
*
* // this will call the real implementation of Foo.someVoidMethod()
* mock.someVoidMethod();
*
*
* See examples in javadoc for {@link Mockito} class
*
* @return stubber - to select a method for stubbing
*/
public static PowerMockitoStubber doCallRealMethod() {
return POWERMOCKITO_CORE.doAnswer(new CallsRealMethods());
}
/**
* Use doNothing() for setting void methods to do nothing. Beware that
* void methods on mocks do nothing by default! However, there are rare
* situations when doNothing() comes handy:
*
* 1. Stubbing consecutive calls on a void method:
*
*
* doNothing().doThrow(new RuntimeException()).when(mock).someVoidMethod();
*
* //does nothing the first time:
* mock.someVoidMethod();
*
* //throws RuntimeException the next time:
* mock.someVoidMethod();
*
*
* 2. When you spy real objects and you want the void method to do nothing:
*
*
* List list = new LinkedList();
* List spy = spy(list);
*
* //let's make clear() do nothing
* doNothing().when(spy).clear();
*
* spy.add("one");
*
* //clear() does nothing, so the list still contains "one"
* spy.clear();
*
*
* See examples in javadoc for {@link Mockito} class
*
* @return stubber - to select a method for stubbing
*/
public static PowerMockitoStubber doNothing() {
return POWERMOCKITO_CORE.doAnswer(DoesNothing.doesNothing());
}
/**
* Use doReturn() in those rare occasions when you cannot use
* {@link Mockito#when(Object)}.
*
* Beware that {@link Mockito#when(Object)} is always recommended for
* stubbing because it is argument type-safe and more readable
* (especially when stubbing consecutive calls).
*
* Here are those rare occasions when doReturn() comes handy:
*
*
* 1. When spying real objects and calling real methods on a spy brings side
* effects
*
*
* List list = new LinkedList();
* List spy = spy(list);
*
* //Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
* when(spy.get(0)).thenReturn("foo");
*
* //You have to use doReturn() for stubbing:
* doReturn("foo").when(spy).get(0);
*
*
* 2. Overriding a previous exception-stubbing:
*
*
* when(mock.foo()).thenThrow(new RuntimeException());
*
* //Impossible: the exception-stubbed foo() method is called so RuntimeException is thrown.
* when(mock.foo()).thenReturn("bar");
*
* //You have to use doReturn() for stubbing:
* doReturn("bar").when(mock).foo();
*
*
* Above scenarios shows a tradeoff of Mockito's ellegant syntax. Note that
* the scenarios are very rare, though. Spying should be sporadic and
* overriding exception-stubbing is very rare.
*
* See examples in javadoc for {@link Mockito} class
*
* @param toBeReturned to be returned when the stubbed method is called
* @return stubber - to select a method for stubbing
*/
public static PowerMockitoStubber doReturn(Object toBeReturned) {
return POWERMOCKITO_CORE.doAnswer(new Returns(toBeReturned));
}
public static PowerMockitoStubber doReturn(Object toBeReturned, Object... othersToBeReturned) {
if (othersToBeReturned != null && othersToBeReturned.length == 0) {
return doReturn(toBeReturned);
}
return POWERMOCKITO_CORE.doAnswer(new ChainReturns(toBeReturned, othersToBeReturned));
}
}