在使用Maven的项目(Eclipse 4.12)中,我成功地使用了JUnit 5和Mockito4.0.0进行测试/ mockig。现在,为了测试受保护的方法,我也想使用PowerMock。
在搜索了一段时间之后,我得到了这个pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>sdi</groupId>
<artifactId>id4mqtt</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Id4Mqtt</name>
<description>Rapid IoT development framework</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.source>1.8</maven.compiler.source>
</properties>
<repositories>
<repository>
<id>Eclipse Paho Repo</id>
<url>%REPOURL%</url>
</repository>
</repositories>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-inline -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>4.0.0</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.geronimo.gshell.support/gshell-io -->
<dependency>
<groupId>org.apache.geronimo.gshell.support</groupId>
<artifactId>gshell-io</artifactId>
<version>1.0-alpha-2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.powermock/powermock-mockito-release-full -->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-mockito-release-full</artifactId>
<version>1.6.4</version>
<type>pom</type>
<scope>test</scope>
</dependency>
</dependencies>
要测试的候选人是(删除不感兴趣的代码)
package applicationBuilder;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class ConfigurationBuilder extends BuilderBase {
private Properties properties;
private String[] uriList;
public ConfigurationBuilder(final Properties aProperties) {
properties = aProperties;
} // ConfigurationBuilder(...)
public Object build(final String aBrokerName) {
List<String> brokerList = grepPropertyKey("[^\\.]+\\.CommunicationMode");
List<MQTTClientDao> clientDaoList = new ArrayList<>();
for(String broker : brokerList) {
clientDaoList.add(buildConfig(broker));
} // rof(broker)
return clientDaoList;
} // build()
protected MQTTClientDao buildConfig(String broker) {
buildUriList(broker);
return new MQTTClientDao(mqttClient, connectOptions);
} // buildConfig
protected void buildUriList(final String aBroker) {
ServerUriBuilder builder = new ServerUriBuilder(properties);
uriList = (String[]) builder.build(aBroker);
} // buildUriList()
} // class
应该测试ServerUriBuilder.build(properties)方法的正确调用的testclass如下所示:
package test.applicationBuilder;
import static org.powermock.api.mockito.PowerMockito.*;
import java.util.Properties;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.legacy.PowerMockRunner;
import applicationBuilder.ConfigurationBuilder;
import applicationBuilder.ServerUriBuilder;
@RunWith(PowerMockRunner.class)
@PrepareForTest(ServerUriBuilder.class)
class ConfigurationBuilderTest {
private static Properties properties;
private static final String BROKER_NAME = "Broker1";
@BeforeEach
void setUp() throws Exception {
properties = new Properties();
}
@AfterEach
void tearDown() throws Exception {
properties = null;
}
@Test
final void testBuildUriList() {
ConfigurationBuilder cut = spy(new ConfigurationBuilder(properties));
try {
verifyPrivate(cut).invoke("buildUriList", BROKER_NAME);
} catch (Exception e) { e.printStackTrace(); }
} // testBuildUriList()
} // class
因为Eclipse没有报告任何错误,所以一切似乎都很好。但是,当我运行测试时,会引发异常:
java.lang.NoClassDefFoundError: org/mockito/cglib/proxy/MethodInterceptor
at org.powermock.api.mockito.PowerMockito.spy(PowerMockito.java:220)
at test.applicationBuilder.ConfigurationBuilderTest.testBuildUriList(ConfigurationBuilderTest.java:130)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:628)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:117)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:184)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:180)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:127)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:68)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:137)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:89)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
Caused by: java.lang.ClassNotFoundException: org.mockito.cglib.proxy.MethodInterceptor
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 55 more
我的问题是:
提前感谢!
发布于 2021-11-25 09:06:05
我想您是在混合Junit版本,而Powermock只与Junit 4兼容。虽然您可以在JUnit 5中使用Junit 4,但由于您使用的是Power假,所以您可能正在运行这个问题。例如,我看到人们使用
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-testng</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>
但是,我建议使用mvn dependency:tree
检查依赖项,而不是将JUnit 5与JUnit 5混合使用。
使用JUnit 5与mockito
如果要使用JUnit5模拟静态方法,则添加与Powermockito相同的Mockito内联依赖项。
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>4.1.0</version>
<scope>test</scope>
</dependency>
对于没有参数的静态方法,您可以使用Java8的::
lambda,我喜欢在一行中使用try/catch
,因为测试完成后不必调用utilities.close();
。
@Test
void givenStaticMethodWithNoArgs_whenMocked_thenReturnsMockSuccessfully() {
assertThat(StaticUtils.name()).isEqualTo("string-to-mock");
try (MockedStatic<StaticUtils> utilities = Mockito.mockStatic(StaticUtils.class)) {
utilities.when(StaticUtils::name).thenReturn("value-name");
assertThat(StaticUtils.name()).isEqualTo("value-name");
}
assertThat(StaticUtils.name()).isEqualTo("string-to-mock");
}
或者用于需要参数的方法
@Test
void givenStaticMethodWithArgs_whenMocked_thenReturnsMockSuccessfully() {
assertThat(StaticUtils.range(2, 6)).containsExactly(2, 3, 4, 5);
try (MockedStatic<StaticUtils> utilities = Mockito.mockStatic(StaticUtils.class)) {
utilities.when(() -> StaticUtils.range(2, 6))
.thenReturn(Arrays.asList(10, 11, 12));
assertThat(StaticUtils.range(2, 6)).containsExactly(10, 11, 12);
}
assertThat(StaticUtils.range(2, 6)).containsExactly(2, 3, 4, 5);
}
正在运行的示例可以找到这里。
https://stackoverflow.com/questions/70095750
复制相似问题