請參考上一篇文檔Mockhtml
http://jmockit.github.io/MockingToolkitComparisonMatrix.htmljava
從模擬支持特性上作了詳細的對比,好比是否支持模擬static、構造函數等等。git
大部分Web應用項目基於Spring平臺構建,集成測試主要關注點是Junit+Spring+Mock集成!
從Spring項目2.x開始就有基於Junit的測試輔助包(Spring-test)!
重點關注引入Mock框架後Spring與其集成!github
舒適提示:Jmockit做爲本文代碼示例的模擬框架,其它模擬選型框架的測試結果直接做爲結論。web
Mock測試框架是否可以和Spring完美集成?spring
虛擬機運行環境版本: 1.7.0_60windows
1)基礎包版本:bash
2)Mock選型:app
3)模擬測試用例框架
備註:實際測試是分開多個測試Demo,spring+mockito
UserService,StaticUserService,UserAction類請參考上一篇文檔Mock
package jmockit; import mockit.NonStrictExpectations; import mockit.Verifications; import org.junit.Test; import org.wit.service.StaticUserService; import org.wit.service.UserAction; public class MockForPublicStaticDemo { @Test public void demo() { new NonStrictExpectations(StaticUserService.class) { { StaticUserService.sayHello(anyString); result = "mock"; } }; // assertEquals("mock", StaticUserService.sayHello("real")); UserAction userAction = new UserAction(); userAction.executeForPublicStatic1("real"); new Verifications() { { StaticUserService.sayHello(anyString); times = 1; } }; } }
package jmockit; import mockit.NonStrictExpectations; import mockit.Verifications; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.wit.service.StaticUserService; import org.wit.service.UserAction; import org.wit.service.UserService; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:applicationContext.xml") public class MockForSpringJunitDemo { @Autowired private UserAction userAction; @Autowired private UserService userService; @Test public void demo() throws Exception { new NonStrictExpectations(StaticUserService.class) { { StaticUserService.sayHello(anyString); result = "mock"; } }; userAction.executeForPublicStatic1("real"); new Verifications() { { StaticUserService.sayHello(anyString); times = 1; } }; } /** * * <pre> * 模擬bean的方法. * UserService sayHello模擬調用, sayHi爲真實調用. * </pre> * * @throws Exception */ @Test public void beanDemo() throws Exception{ new NonStrictExpectations(userService) { { userService.sayHello(anyString); result = "mock"; } }; userAction.executeForPublic("hi"); new Verifications() { { userService.sayHello(anyString); times = 1; } }; } }
package jmockit; import static mockit.Deencapsulation.invoke; import mockit.Expectations; import mockit.Verifications; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.wit.service.StaticUserService; import org.wit.service.UserAction; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:applicationContext.xml") public class MockForSpringJunitPrivateStaticDemo { @Autowired private UserAction userAction; @Test public void demo() throws Exception { new Expectations(StaticUserService.class) { { invoke(StaticUserService.class, "secreteSayHi", anyString); invoke(StaticUserService.class, "secreteSayHello", anyString); result = "mock"; } }; userAction.executeForPrivateStatic("real"); new Verifications() { { invoke(StaticUserService.class, "secreteSayHi", anyString); times = 1; invoke(StaticUserService.class, "secreteSayHello", anyString); times = 1; } }; } }
方案:Mockito:1.9.5, PowerMock-mockito-*: 1.5.5
2015-11-27 15:58:48,015 INFO context.TestContextManager - Could not instantiate TestExecutionListener class [org.springframework.test.context.web.ServletTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their dependencies) available. 2015-11-27 15:58:48,019 INFO context.TestContextManager - Could not instantiate TestExecutionListener class [org.springframework.test.context.transaction.TransactionalTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their dependencies) available. 2015-11-27 15:58:48,112 INFO xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [applicationContext.xml] 2015-11-27 15:58:48,191 INFO support.GenericApplicationContext - Refreshing org.springframework.context.support.GenericApplicationContext@361fc5a2: startup date [Fri Nov 27 15:58:48 GMT+08:00 2015]; root of context hierarchy # # A fatal error has been detected by the Java Runtime Environment: # # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000000000291e2ba, pid=15700, tid=14928 # # JRE version: Java(TM) SE Runtime Environment (7.0_60-b13) (build 1.7.0_60-ea-b13) # Java VM: Java HotSpot(TM) 64-Bit Server VM (24.60-b09 mixed mode windows-amd64 compressed oops) # Problematic frame: # j java.lang.reflect.ReflectAccess.copyField(Ljava/lang/reflect/Field;)Ljava/lang/reflect/Field;+1 # # Failed to write core dump. Minidumps are not enabled by default on client versions of Windows # # An error report file with more information is saved as: # D:\workspace\workspace-demos\mockito\hs_err_pid15700.log Compiled method (c2) 861 16 java.lang.Object::<init> (1 bytes) total in heap [0x0000000002969310,0x0000000002969540] = 560 relocation [0x0000000002969430,0x0000000002969440] = 16 main code [0x0000000002969440,0x00000000029694c0] = 128 stub code [0x00000000029694c0,0x00000000029694d8] = 24 oops [0x00000000029694d8,0x00000000029694e0] = 8 scopes data [0x00000000029694e0,0x00000000029694f0] = 16 scopes pcs [0x00000000029694f0,0x0000000002969520] = 48 dependencies [0x0000000002969520,0x0000000002969528] = 8 handler table [0x0000000002969528,0x0000000002969540] = 24 # # If you would like to submit a bug report, please visit: # http://bugreport.sun.com/bugreport/crash.jsp #
方案: Jmock:2.6.0,Jmockit:1.14