All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.powermock.api.mockito.PowerMockito Maven / Gradle / Ivy

There is a newer version: 1.7.4
Show newest version
/*
s * Copyright 2008 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.MockingProgress;
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.MockCreator;
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) {
        MockCreator.mock(type, true, false, null, null, (Method[]) null);
        if(types != null && types.length > 0) {
            for (Class aClass : types) {
                MockCreator.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 * * @return mock object */ 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 * @return mock object */ public static void mockStatic(Class classToMock, MockSettings mockSettings) { MockCreator.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 MockCreator.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 MockCreator.mock(classToMock, false, false, null, mockSettings, (Method[]) null); } /** * Spy on objects that are final or otherwise not "spyable" from * normal Mockito. * * @see Mockito#spy(Object) * * @param * the type of the mock object * @param object * the object to spy on * @return the spy object. */ @SuppressWarnings("unchecked") public static synchronized T spy(T object) { return MockCreator.mock((Class) Whitebox.getType(object), false, true, object, null, (Method[]) null); } /** * Spy on classes (not "spyable" from normal Mockito). * * @see Mockito#spy(Object) * * @param * the type of the class mock * @param type * the type of the class mock */ public static synchronized void spy(Class type) { MockCreator.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) { Whitebox.getInternalState(Mockito.class, MockingProgress.class).verificationStarted( POWERMOCKITO_CORE.wrapInStaticVerificationMode(verificationMode)); } /** * Verify a private method invocation for an instance. * * @see {@link Mockito#verify(Object)} * @throws Exception * If something unexpected goes wrong. */ public static PrivateMethodVerification verifyPrivate(Object object) throws Exception { return verifyPrivate(object, times(1)); } /** * Verify a private method invocation with a given verification mode. * * @see {@link Mockito#verify(Object)} * @throws Exception * If something unexpected goes wrong. */ public static PrivateMethodVerification verifyPrivate(Object object, VerificationMode verificationMode) throws Exception { Whitebox.getInternalState(Mockito.class, MockingProgress.class).verificationStarted( POWERMOCKITO_CORE.wrapInMockitoSpecificVerificationMode(object, verificationMode)); return new DefaultPrivateMethodVerification(object); } /** * Verify a private method invocation for a class. * * @see {@link Mockito#verify(Object)} * @throws Exception * If something unexpected goes wrong. */ 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. * * @see {@link Mockito#verify(Object)} * @throws Exception * If something unexpected goes wrong. */ 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. * * @see {@link Mockito#when(Object)} * @throws Exception * If something unexpected goes wrong. */ 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. * * @see {@link Mockito#when(Object)} * @throws Exception * If something unexpected goes wrong. */ public static WithOrWithoutExpectedArguments when(Object instance, Method method) throws Exception { return new DefaultMethodExpectationSetup(instance, method); } /** * Expect calls to private static methods. * * @see {@link Mockito#when(Object)} * @throws Exception * If something unexpected goes wrong. */ 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). * * @see {@link Mockito#when(Object)} * @throws Exception * If something unexpected goes wrong. */ 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. * * @see {@link Mockito#when(Object)} * @throws Exception * If something unexpected goes wrong. */ 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 * * @see {@link Mockito#when(Object)} * @throws Exception * If something unexpected goes wrong. */ 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(new 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)); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy