Skip to content

Commit

Permalink
Fixes #726 Mockito Public API Support
Browse files Browse the repository at this point in the history
Remove reseting mocking process in PowerMockito
  • Loading branch information
Arthur Zagretdinov authored and thekingn0thing committed Sep 10, 2017
1 parent 9be004f commit f03b127
Show file tree
Hide file tree
Showing 14 changed files with 48 additions and 97 deletions.
4 changes: 3 additions & 1 deletion docs/changelog.txt
@@ -1,5 +1,7 @@
Change log 2.0.0
* Public Mockito support:
* PowerMockito changes:
** `verifyStatic` is replaced by `verifyStatic(Class)`
** `mockStatic` does not reset mocking process anymore. As result you may get the `UnfinishedVerificationException` or `UnfinishedStubbingException`
** Possible incapability due toString methods returns by default name of mocked.

Change log 1.7.1
Expand Down
Expand Up @@ -1471,7 +1471,7 @@ public static synchronized void verify(Object... objects) {
if (mock instanceof Class<?>) {
verifyClass((Class<?>) mock);
} else {
MethodInvocationControl invocationControl = MockRepository.getInstanceMethodInvocationControl(mock);
EasyMockMethodInvocationControl invocationControl = (EasyMockMethodInvocationControl) MockRepository.getInstanceMethodInvocationControl(mock);
if (invocationControl != null) {
invocationControl.verify();
} else {
Expand Down Expand Up @@ -2078,11 +2078,11 @@ private static synchronized void replay(Class<?>... types) {
*/
private static synchronized void verifyClass(Class<?>... types) {
for (Class<?> type : types) {
final MethodInvocationControl invocationHandler = MockRepository.getStaticMethodInvocationControl(type);
final EasyMockMethodInvocationControl invocationHandler = (EasyMockMethodInvocationControl) MockRepository.getStaticMethodInvocationControl(type);
if (invocationHandler != null) {
invocationHandler.verify();
}
NewInvocationControl<?> newInvocationControl = MockRepository.getNewInstanceControl(type);
NewInvocationControlImpl<?> newInvocationControl = (NewInvocationControlImpl<?>) MockRepository.getNewInstanceControl(type);
if (newInvocationControl != null) {
try {
newInvocationControl.verify();
Expand Down
Expand Up @@ -120,7 +120,6 @@ public synchronized Object replay(Object... mocks) {
return null;
}

@Override
public synchronized Object verify(Object... mocks) {
// Silently ignore verify if someone has verified the mock before.
if (!hasVerified) {
Expand Down
Expand Up @@ -25,6 +25,7 @@

import java.lang.reflect.Constructor;

//TODO rename to EasyMock
public class NewInvocationControlImpl<T> implements NewInvocationControl<IExpectationSetters<T>> {
private final InvocationSubstitute<T> substitute;
private final Class<T> subsitutionType;
Expand Down Expand Up @@ -85,7 +86,6 @@ public synchronized Object replay(Object... mocks) {
return null;
}

@Override
public synchronized Object verify(Object... mocks) {
if (!hasVerified) {
EasyMock.verify(substitute);
Expand Down
Expand Up @@ -18,8 +18,6 @@

import org.mockito.MockSettings;
import org.mockito.Mockito;
import org.mockito.internal.progress.MockingProgress;
import org.mockito.internal.progress.ThreadSafeMockingProgress;
import org.mockito.stubbing.Answer;
import org.mockito.stubbing.OngoingStubbing;
import org.mockito.verification.VerificationMode;
Expand All @@ -31,14 +29,11 @@
import org.powermock.api.mockito.internal.PowerMockitoCore;
import org.powermock.api.mockito.internal.expectation.DefaultMethodExpectationSetup;
import org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator;
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;
Expand All @@ -55,7 +50,7 @@
* @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();

/**
Expand All @@ -64,7 +59,6 @@ public class PowerMockito extends MemberModifier {
* @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) {
Expand Down Expand Up @@ -118,7 +112,6 @@ public static void mockStatic(Class<?> classMock, @SuppressWarnings("rawtypes")
* @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);
}

Expand Down Expand Up @@ -211,7 +204,6 @@ public static synchronized <T> T spy(T object) {
* @see PowerMockito#spy(Object)
*/
public static synchronized <T> void spy(Class<T> type) {
ThreadSafeMockingProgress.mockingProgress().reset();
MockSettings mockSettings = Mockito.withSettings().defaultAnswer(Mockito.CALLS_REAL_METHODS);
DefaultMockCreator.mock(type, true, true, type, mockSettings, (Method[]) null);
}
Expand Down Expand Up @@ -288,8 +280,7 @@ public static PrivateMethodVerification verifyPrivate(Object object) throws Exce
* @throws Exception If something unexpected goes wrong.
* @see Mockito#verify(Object)
*/
public static PrivateMethodVerification verifyPrivate(Object object, VerificationMode verificationMode)
throws Exception {
public static PrivateMethodVerification verifyPrivate(Object object, VerificationMode verificationMode) throws Exception {
Mockito.verify(object, verificationMode);
return new DefaultPrivateMethodVerification(object);
}
Expand All @@ -311,8 +302,7 @@ public static PrivateMethodVerification verifyPrivate(Class<?> clazz) throws Exc
* @throws Exception If something unexpected goes wrong.
* @see Mockito#verify(Object)
*/
public static PrivateMethodVerification verifyPrivate(Class<?> clazz, VerificationMode verificationMode)
throws Exception {
public static PrivateMethodVerification verifyPrivate(Class<?> clazz, VerificationMode verificationMode) throws Exception {
return verifyPrivate((Object) clazz, verificationMode);
}

Expand All @@ -337,16 +327,7 @@ public static PrivateMethodVerification verifyPrivate(Class<?> clazz, Verificati
*/
@SuppressWarnings("unchecked")
public static synchronized <T> ConstructorArgumentsVerification verifyNew(Class<T> 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<T>((NewInvocationControl<T>) invocationControl, mock);
return verifyNew(mock, times(1));
}

/**
Expand All @@ -369,23 +350,8 @@ public static synchronized <T> ConstructorArgumentsVerification verifyNew(Class<
* @param mode times(x), atLeastOnce() or never()
*/
@SuppressWarnings("unchecked")
public static <T> 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<T>((NewInvocationControl<T>) invocationControl, mock);
public static <T> ConstructorArgumentsVerification verifyNew(Class<T> mock, VerificationMode mode) {
return POWERMOCKITO_CORE.verifyNew(mock, mode);
}

/**
Expand Down
Expand Up @@ -17,20 +17,26 @@
package org.powermock.api.mockito.internal;

import org.mockito.Mockito;
import org.mockito.internal.progress.MockingProgress;
import org.mockito.internal.progress.ThreadSafeMockingProgress;
import org.mockito.internal.verification.MockAwareVerificationMode;
import org.mockito.stubbing.Answer;
import org.mockito.stubbing.Stubber;
import org.mockito.verification.VerificationMode;
import org.powermock.api.mockito.expectation.PowerMockitoStubber;
import org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl;
import org.powermock.api.mockito.internal.invocation.MockitoNewInvocationControl;
import org.powermock.api.mockito.internal.verification.DefaultConstructorArgumentsVerification;
import org.powermock.core.MockRepository;
import org.powermock.core.classloader.ClassloaderWrapper;
import org.powermock.core.spi.NewInvocationControl;
import org.powermock.reflect.Whitebox;

import java.util.concurrent.Callable;

import static org.powermock.utils.Asserts.assertNotNull;

public class PowerMockitoCore {

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.";

public PowerMockitoStubber doAnswer(final Answer answer) {
return doAnswer(new Callable<Stubber>() {
@Override
Expand Down Expand Up @@ -85,16 +91,20 @@ public Stubber call() throws Exception {
});
}

private PowerMockitoStubber doAnswer(final Callable<Stubber> callable) {
final Stubber stubber = ClassloaderWrapper.runWithClass(callable);
return new PowerMockitoStubberImpl(stubber);
}
public <T> DefaultConstructorArgumentsVerification<T> verifyNew(final Class<T> mock, final VerificationMode mode) {
assertNotNull(mock, "Class to verify cannot be null");
assertNotNull(mode, "Verify mode cannot be null");

MockitoNewInvocationControl<T> invocationControl = (MockitoNewInvocationControl<T>) MockRepository.getNewInstanceControl(mock);

assertNotNull(invocationControl, String.format(NO_OBJECT_CREATION_ERROR_MESSAGE_TEMPLATE, Whitebox.getType(mock).getName()));

private MockingProgress getMockingProgress() {
return ThreadSafeMockingProgress.mockingProgress();
invocationControl.verify(mode);
return new DefaultConstructorArgumentsVerification<T>((NewInvocationControl<T>) invocationControl, mock);
}

public MockAwareVerificationMode wrapInMockitoSpecificVerificationMode(Object mock, VerificationMode mode) {
return new MockAwareVerificationMode(mock, mode, getMockingProgress().verificationListeners());
private PowerMockitoStubber doAnswer(final Callable<Stubber> callable) {
final Stubber stubber = ClassloaderWrapper.runWithClass(callable);
return new PowerMockitoStubberImpl(stubber);
}
}
Expand Up @@ -19,16 +19,13 @@
import org.mockito.exceptions.base.MockitoAssertionError;
import org.mockito.stubbing.OngoingStubbing;
import org.mockito.verification.VerificationMode;
import org.powermock.core.MockRepository;
import org.powermock.core.spi.NewInvocationControl;
import org.powermock.core.spi.support.InvocationSubstitute;
import org.powermock.reflect.internal.WhiteboxImpl;

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;

import static org.mockito.Mockito.times;

public class MockitoNewInvocationControl<T> implements NewInvocationControl<OngoingStubbing<T>> {
private final InvocationSubstitute<T> substitute;

Expand All @@ -49,7 +46,7 @@ public Object invoke(Class<?> type, Object[] args, Class<?>[] sig) throws Except
args = new Object[args.length + varArgsLength - 1];
System.arraycopy(oldArgs, 0, args, 0, oldArgs.length - 1);
for (int i = oldArgs.length - 1, j=0; i < args.length; i++, j++) {
args[i] = Array.get(varArgs, j);
args[i] = Array.get(varArgs, j);
}
}
try {
Expand All @@ -75,24 +72,10 @@ public InvocationSubstitute<T> getSubstitute() {
public synchronized Object replay(Object... mocks) {
return null;
}

@Override
public synchronized Object verify(Object... mocks) {
final VerificationMode verificationMode;
Object mode = MockRepository.getAdditionalState("VerificationMode");
if (mode != null) {
if (mode instanceof VerificationMode) {
verificationMode = (VerificationMode) mode;
} else {
throw new IllegalStateException("Internal error. VerificationMode in MockRepository was not of type "
+ VerificationMode.class.getName() + ".");
}
} else {
verificationMode = times(1);
}
Mockito.verify(substitute, verificationMode);
return null;
}

public synchronized void verify(final VerificationMode verificationMode) {
Mockito.verify(substitute, verificationMode);
}

@SuppressWarnings("unchecked")
@Override
Expand Down
Expand Up @@ -22,13 +22,13 @@
import org.powermock.api.mockito.verification.ConstructorArgumentsVerification;
import org.powermock.core.spi.NewInvocationControl;

public class DefaultConstructorArgumentsVerfication<T> implements ConstructorArgumentsVerification {
public class DefaultConstructorArgumentsVerification<T> implements ConstructorArgumentsVerification {

private final MockitoNewInvocationControl<T> invocationControl;
private final Class<?> type;

@SuppressWarnings("unchecked")
public DefaultConstructorArgumentsVerfication(NewInvocationControl<T> invocationControl, Class<?> type) {
public DefaultConstructorArgumentsVerification(NewInvocationControl<T> invocationControl, Class<?> type) {
this.type = type;
this.invocationControl = (MockitoNewInvocationControl<T>) invocationControl;
}
Expand Down
Expand Up @@ -132,7 +132,6 @@ public Object reset(Object... mocks) {
throw new IllegalStateException("Internal error: No such thing as reset exists in Mockito.");
}

@Override
public Object verify(Object... mocks) {
if (mocks == null || mocks.length != 1) {
throw new IllegalArgumentException("Must supply one mock to the verify method.");
Expand Down
Expand Up @@ -33,17 +33,6 @@ public interface DefaultBehavior {
*/
Object replay(Object... mocks);

/**
* Verify the given objects or classes. May throw exception if verify is not
* needed or not supported.
*
* @param mocks
* The object(s) to verify. May be {@code null}.
*
* @return the result of the verification (may be {@code null}).
*/
Object verify(Object... mocks);

/**
* Reset the given objects or classes. May throw exception if reset is not
* needed or not supported.
Expand Down
Expand Up @@ -44,6 +44,7 @@ public void largeMethodShouldBeAbleToBeMocked() {
when(InterfaceMethodExceedingJvmLimit.init()).thenReturn("ok");
assertEquals("Mocked method should return: ok", "ok", InterfaceMethodExceedingJvmLimit.init());
verifyStatic(InterfaceMethodExceedingJvmLimit.class);
InterfaceMethodExceedingJvmLimit.init();
}

@Test(expected = IllegalStateException.class)
Expand All @@ -52,5 +53,6 @@ public void largeMethodShouldBeAbleToBeMockedAndThrowException() {
when(InterfaceMethodExceedingJvmLimit.init()).thenThrow(new IllegalStateException());
InterfaceMethodExceedingJvmLimit.init();
verifyStatic(InterfaceMethodExceedingJvmLimit.class);
InterfaceMethodExceedingJvmLimit.init();
}
}
Expand Up @@ -46,6 +46,7 @@ public void largeMethodShouldBeAbleToBeMocked() {
when(MethodExceedingJvmLimit.init()).thenReturn("ok");
assertEquals("Mocked method should return: ok", "ok", MethodExceedingJvmLimit.init());
verifyStatic(MethodExceedingJvmLimit.class);
MethodExceedingJvmLimit.init();
}

@Test(expected = IllegalStateException.class)
Expand All @@ -54,5 +55,6 @@ public void largeMethodShouldBeAbleToBeMockedAndThrowException() {
when(MethodExceedingJvmLimit.init()).thenThrow(new IllegalStateException());
MethodExceedingJvmLimit.init();
verifyStatic(MethodExceedingJvmLimit.class);
MethodExceedingJvmLimit.init();
}
}
Expand Up @@ -79,6 +79,7 @@ public void should_not_verify_behaviour_of_another_mock_class_not_specified_in_v
verifyStatic(StaticService.class);

SimpleStaticService.say("Something");
StaticService.sayHello();
}

@Test
Expand Down

0 comments on commit f03b127

Please sign in to comment.