目录
- Mock测试的概念
- Mockito的使用
- Mock静态方法
参考:
Mock测试的概念
单元测试,是验证代码逻辑一个非常重要的手段。其中Mockito单元测试包,可以对Bean依赖的外部Bean逻辑进行Mock,使得开发人员只需要关注本Bean内的逻辑正确与否
Mockito的使用
依赖
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.9</version> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>1.10.19</version> </dependency>
模板
@RunWith(MockitoJunitRunner.class) public class Test{ // 待测试的类 private TestService testService; // 一些其他属性 // 在testService需要测试的方法中,有外部依赖的Bean,进行Mock操作 @Mock private UsedBean1 u1; @Mock private UsedBean2 u2; @Before public void before(){ // 创建测试对象 testService = new TestService(); testService.setU1(u1); testService.setU2(u2); // 其他逻辑 } // 测试方法 @Test public void test(){ // Mock外部依赖Bean的方法 Mockito.when(u1.method1(Mockito.any())).thenReturn("..."); Mockito.when(u2.method2(Mockito.any())).thenReturn("..."); // 其他测试参数设置 // 测试方法 String result = testService.test(); Assert.equals(result, new Result().toString()); } // 测试抛异常逻辑 @Test public void exception_test(){ try { long data = Long.parseLong("???"); // fail("NumberFormatException is not thrown as expected"); } catch (Exception e) { assertTrue(e != null); } } // 测试priavte方法 @Test public void private_method_test(){ // 使用java的反射机制 Class<TestService> clz = testService.getClass(); // 测试TestService的 private String test(Long arg)方法 Method method = clz.getDeclaredMethod("test", Long.class); method.setAccessible(true); Assert.assertEquals("1", method.invoke(testService, 1)); method.setAccessible(false); } }
Mock静态方法
需要使用powerMock
- 依赖
<!--PowerMock-->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.2</version>
<scope>test</scope>
</dependency>
注意和mockito的依赖版本兼容性
Mockito PowerMock
1.10.8+ 1.6.2+
1.9.5-rc1 - 1.9.5 1.5.0 - 1.5.6
1.9.0-rc1 & 1.9.0 1.4.10 - 1.4.12
1.8.5 1.3.9 to 1.4.9
1.8.4 1.3.7 & 1.3.8
1.8.3 1.3.6
1.8.1 & 1.8.2 1.3.5
1.8 1.3
1.7 1.2.5
- 测试类
public class ClassUnderTest {
public boolean callStaticMethod() {
return ClassDependency.isExist();
}
}
public class ClassDependency {
public static boolean isExist() {
return false;
}
}
@RunWith(PowerMockRunner.class)
@PrepareForTest(value = {ClassDependency.class})
public class TestClassUnderTest {
@Test
public void testCallStaticMethod() {
ClassUnderTest underTest = new ClassUnderTest();
PowerMockito.mockStatic(ClassDependency.class);
PowerMockito.when(ClassDependency.isExist()).thenReturn(true);
Assert.assertTrue(underTest.callStaticMethod());
}
}
- 避坑
直接启动有时候会报错
ERROR Could not reconfigure JMX java.lang.LinkageError: loader constraint violation: loader (instance of org/powermock/core/classloader/MockClassLoader) previously initiated loading for a different type with name "javax/management/MBeanServer"
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at org.powermock.core.classloader.MockClassLoader.loadUnmockedClass(MockClassLoader.java:262)
at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:206)
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass1(DeferSupportingClassLoader.java:89)
at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:79)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.apache.logging.log4j.core.jmx.Server.unregisterAllMatching(Server.java:335)
at org.apache.logging.log4j.core.jmx.Server.unregisterLoggerContext(Server.java:259)
at org.apache.logging.log4j.core.jmx.Server.reregisterMBeansAfterReconfigure(Server.java:164)
at org.apache.logging.log4j.core.jmx.Server.reregisterMBeansAfterReconfigure(Server.java:140)
at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:556)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:617)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:634)
at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:229)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:152)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getContext(AbstractLoggerAdapter.java:122)
at org.apache.logging.slf4j.Log4jLoggerFactory.getContext(Log4jLoggerFactory.java:43)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:46)
at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:29)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:358)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383)
需要在测试类上添加这个注解即可
@PowerMockIgnore({"javax.management.*"})