写在开头
本文仅仅示范基础使用方法,仅仅提供一个快速入门的遍历,后续的高级操作还需各位自己探索。
Mockito与PowerMock基础使用说明
maven引用
1 2 3 4 5 6 7 8 9 10 11 12 13
| <!-- 要求junit为4+ --> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>1.7.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito</artifactId> <version>1.7.0</version> <scope>test</scope> </dependency>
|
通用基础设置
1 2 3 4 5 6 7 8
| @RunWith(PowerMockRunner.class) @PowerMockIgnore({"javax.net.ssl.*","javax.crypto.*","org.xml.*", "javax.xml.*"}) public class BasedTest { @Test public void baseTest() { System.out.println("hello mockito."); } }
|
该类将作为所有测试方法的父类,因为@RunWith(PowerMockRunner.class)
是使用PowerMock和Mockito的必备注解,每个测试类均需要,@PowerMockIgnore
是为了解决特殊异常:
By default PowerMock loads all classes with its MockClassLoader. The classloader loads and modified all classes except:
system classes. They are deferred to system classloader
classes located in packages that are specified as ignored.
其中,javax.net.ssl.*
针对网络使用,javax.crypto.*
针对加密方法,org.xml.*
与javax.xml.*
针对xml文件解析方法。
静态方法
1 2 3 4 5 6 7 8 9
| public class Static { public static String staticMethod() { return "static"; }
public static String staticWithParam(String param) { return param + "_"; } }
|
针对上述静态方法,测试类代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| @PrepareForTest(Static.class) public class StaticTest extends BasedTest {
@Before public void init() { PowerMockito.mockStatic(Static.class); }
@Test public void testStaticMethod() { Mockito.when(Static.staticMethod()).thenReturn("mockito static"); Assert.assertEquals("mockito static", Static.staticMethod()); }
@Test public void testStaticWithParam() { Mockito.when(Static.staticWithParam("test")).thenReturn("mockito static"); Mockito.when(Static.staticWithParam("static")).thenReturn("static_"); Assert.assertEquals("static_", Static.staticWithParam("static")); Assert.assertEquals("mockito static", Static.staticWithParam("test")); Assert.assertEquals(null, Static.staticWithParam("null")); }
@Test public void testStaticWithParamBySpy() { PowerMockito.spy(Static.class); PowerMockito.when(Static.staticWithParam("test")).thenReturn("mockito static"); Assert.assertEquals("static_", Static.staticWithParam("static")); Assert.assertEquals("mockito static", Static.staticWithParam("test")); } }
|
针对有参静态方法,使用了spy
作为特殊处理,因为使用该方法后,当调用参数为设置规则之外参数,将会调用原生方法执行,如果如同注释部分代码,规则之外参数将只会通过mock执行,有返回值的方法只会返回null。可以通过方法testStaticWithParam
与testStaticWithParamBySpy
进行对比。最简单明了的好处就是添加了spy
后可以针对源代码debug,是可以测试具体的代码逻辑的。注意需要配合注解@PrepareForTest(Static.class)
联合使用。
整体待测试项目结构与代码
1 2 3 4 5 6 7
| st=>start: Start e=>end opc=>operation: controller ops=>operation: service opm=>operation: mapper
st->opc->ops->opm->e
|
具体代码:
Controller:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @Controller public class TestController { @Autowired private TestService testService;
@RequestMapping("testMethod") @ResponseBody public String testMethod() { return testService.test(); }
@RequestMapping("testMethodWithParam") @ResponseBody public String testMethodWithParam(Map<String, String> param) { return testService.testWithParam(param); } }
|
Service:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public interface TestService { String test();
String testWithParam(Map<String, String> param);
String testPrivateMethod(String param); }
@Service public class TestServiceImpl implements TestService { @Autowired private TestMapper testMapper; @Override public String test() { return testMapper.test(); }
@Override public String testWithParam(Map<String, String> param) { return String.valueOf(param.size()); }
@Override public String testPrivateMethod(String param) { return privateMethod(param); }
private String privateMethod(String param) { return param + "---"; } }
|
Mapper:
1 2 3
| public interface TestMapper { String test(); }
|
基础测试
controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| public class TestControllerTest extends BasedTest {
@Mock private TestService testService;
@Autowired @InjectMocks private TestController testController;
@Test public void testTestMethod() { Mockito.when(testService.test()).thenReturn("mockito"); Assert.assertEquals("mockito", testController.testMethod()); }
@Test public void testTestMethodWithParam() { Map<String,String> test = new HashMap<>(); test.put("1","2"); PowerMockito.when(testService.testWithParam(Mockito.any())).thenReturn("others"); PowerMockito.when(testService.testWithParam(test)).thenReturn("1-2"); Map<String,String> change = new HashMap<>(); change.put("1","2"); Assert.assertEquals("1-2", testController.testMethodWithParam(change)); Map<String,String> change2 = new HashMap<>(); change2.put("1","2"); change2.put("2","3"); Assert.assertEquals("others", testController.testMethodWithParam(change2)); }
@Test public void testTestMethodWithParamBySpy() throws Exception { TestServiceImpl spy = PowerMockito.spy(new TestServiceImpl()); Map<String,String> test = new HashMap<>(); test.put("1","2"); PowerMockito.doReturn("mockito").when(spy, "testWithParam", test); Map<String,String> change = new HashMap<>(); change.put("1","2"); Assert.assertEquals("mockito", spy.testWithParam(change)); Map<String,String> change2 = new HashMap<>(); change2.put("1","2"); change2.put("2","3"); Assert.assertEquals("2", spy.testWithParam(change2)); } }
|
service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| @PrepareForTest(TestServiceImpl.class) public class TestServiceTest extends BasedTest { @Mock private TestMapper testMapper;
@Autowired @InjectMocks private TestServiceImpl testService;
@Test public void testTest() { Mockito.when(testMapper.test()).thenReturn("mockito"); Assert.assertEquals("mockito", testService.test()); }
@Test public void testPrivateMethod() throws Exception { TestServiceImpl spy = PowerMockito.spy(new TestServiceImpl()); PowerMockito.when(spy, "privateMethod", "test").thenReturn("mockito"); Assert.assertEquals("mockito", spy.testPrivateMethod("test")); Assert.assertEquals("test2---", spy.testPrivateMethod("test2")); } }
|
Tips:需格外注意注解@PrepareForTest(TestServiceImpl.class)