测试 void 方法中的静态方法已被调用一次
Testing that static method inside void method has been called once
我需要一些测试方面的帮助。有以下方法:
@PrePersist
public void prePersist(Tag tag) {
if (tagService.listUserTags(tag.getUser())
.size() > Constants.Tags.maxPerUser) {
TaskUtils.createTask(url, param);
}
}
我想测试一下TaskUtils.createTask()被调用了一次,但是我不想里面的代码被执行。我试过这样:
@Test
@PrepareForTest(TaskUtils.class)
public void testPrePersistMethodWhenTagCountOverLimit() {
[...]
when(tags.size()).thenReturn(Constants.Tags.maxPerUser + 1);
when (tagService.listUserTags(tag.getUser())).thenReturn(tags);
PowerMockito.mockStatic(TaskUtils.class);
PowerMockito.doNothing().when(TaskUtils.class, "createTask", Mockito.any(String.class), Mockito.any(String.class));
Method method = ClassUtils.getMethodWithAnnotation(TagListener.class, PrePersist.class);
method.invoke(tagListener, tag); //here the prePersist method is called
PowerMockito.verifyStatic( Mockito.times(1));
}
但是方法TaskUtils.createTask()实际上是在执行doNothing的情况下执行的。
堆栈跟踪的一部分:
java.lang.NullPointerException
at fi.util.TaskUtils.createTask(TaskUtils.java:90)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.powermock.reflect.internal.WhiteboxImpl.performMethodInvocation(WhiteboxImpl.java:1873)
at org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:773)
at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:753)
at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:466)
at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:106)
at fi.intra.test.domain.listener.TestTagListener.testPrePersistMethodWhenTagCountOverLimit(TestTagListener.java:92)
有什么想法吗?
以下有效并且应该等同于您的情况:
我使用Gradle构建,并添加了以下依赖:
testCompile group: 'org.powermock', name: 'powermock-mockito-release-full', version: '1.6.4'
测试
package sojava.mocking;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.times;
import static org.powermock.api.mockito.PowerMockito.*;
@RunWith(PowerMockRunner.class)
@PrepareForTest(MyData.class)
public class PowerMockitoTests {
@Test
public void static_method_when_mocked_does_nothing() throws Exception {
int amount = 123;
// Arrange
mockStatic(MyData.class);
doNothing().when(MyData.class, "increment", amount);
// Action
new MyDataWrapper().increment(amount);
verifyStatic(times(1));
MyData.increment(amount);
// Assert
assertThat(MyData.getCount()).isEqualTo(0);
}
}
你见过这段代码吗?
new MyDataWrapper().increment(amount);
verifyStatic(times(1));
MyData.increment(amount);
这很尴尬,但这就是它的工作原理。想要测试一个静态方法被调用了多次?然后你调用那个方法,然后调用 verifyStatic()
,然后再次调用那个静态方法。最后一次调用将触发检查。
Class 使用静态方法
package sojava.mocking;
public class MyDataWrapper {
public void increment(int amount) {
MyData.increment(amount);
}
}
Class 包含静态方法
包 sojava.mocking;
public class MyData {
private static int count = 0;
private MyData() {
}
public static void increment(int amount) {
count += amount;
}
public static int getCount() {
return count;
}
}
更多样本: 更多样本位于 Github page on the tests
folder.
我需要一些测试方面的帮助。有以下方法:
@PrePersist
public void prePersist(Tag tag) {
if (tagService.listUserTags(tag.getUser())
.size() > Constants.Tags.maxPerUser) {
TaskUtils.createTask(url, param);
}
}
我想测试一下TaskUtils.createTask()被调用了一次,但是我不想里面的代码被执行。我试过这样:
@Test
@PrepareForTest(TaskUtils.class)
public void testPrePersistMethodWhenTagCountOverLimit() {
[...]
when(tags.size()).thenReturn(Constants.Tags.maxPerUser + 1);
when (tagService.listUserTags(tag.getUser())).thenReturn(tags);
PowerMockito.mockStatic(TaskUtils.class);
PowerMockito.doNothing().when(TaskUtils.class, "createTask", Mockito.any(String.class), Mockito.any(String.class));
Method method = ClassUtils.getMethodWithAnnotation(TagListener.class, PrePersist.class);
method.invoke(tagListener, tag); //here the prePersist method is called
PowerMockito.verifyStatic( Mockito.times(1));
}
但是方法TaskUtils.createTask()实际上是在执行doNothing的情况下执行的。 堆栈跟踪的一部分:
java.lang.NullPointerException
at fi.util.TaskUtils.createTask(TaskUtils.java:90)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.powermock.reflect.internal.WhiteboxImpl.performMethodInvocation(WhiteboxImpl.java:1873)
at org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:773)
at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:753)
at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:466)
at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:106)
at fi.intra.test.domain.listener.TestTagListener.testPrePersistMethodWhenTagCountOverLimit(TestTagListener.java:92)
有什么想法吗?
以下有效并且应该等同于您的情况:
我使用Gradle构建,并添加了以下依赖:
testCompile group: 'org.powermock', name: 'powermock-mockito-release-full', version: '1.6.4'
测试
package sojava.mocking;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.times;
import static org.powermock.api.mockito.PowerMockito.*;
@RunWith(PowerMockRunner.class)
@PrepareForTest(MyData.class)
public class PowerMockitoTests {
@Test
public void static_method_when_mocked_does_nothing() throws Exception {
int amount = 123;
// Arrange
mockStatic(MyData.class);
doNothing().when(MyData.class, "increment", amount);
// Action
new MyDataWrapper().increment(amount);
verifyStatic(times(1));
MyData.increment(amount);
// Assert
assertThat(MyData.getCount()).isEqualTo(0);
}
}
你见过这段代码吗?
new MyDataWrapper().increment(amount);
verifyStatic(times(1));
MyData.increment(amount);
这很尴尬,但这就是它的工作原理。想要测试一个静态方法被调用了多次?然后你调用那个方法,然后调用 verifyStatic()
,然后再次调用那个静态方法。最后一次调用将触发检查。
Class 使用静态方法
package sojava.mocking;
public class MyDataWrapper {
public void increment(int amount) {
MyData.increment(amount);
}
}
Class 包含静态方法
包 sojava.mocking;
public class MyData {
private static int count = 0;
private MyData() {
}
public static void increment(int amount) {
count += amount;
}
public static int getCount() {
return count;
}
}
更多样本: 更多样本位于 Github page on the tests
folder.