常規(guī)的單元測試只需要引入springboot-test包,其會(huì)帶入junit勋又,mockito-core玄柏,spring-test
<!-- unit test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
單元測試class如下,如果不需要起spring環(huán)境的話可以不要@SpringBootTest和@RunWith:
@SpringBootTest
@RunWith(SpringRunner.class)
public class ContractServiceTest {
@Mock
private IParameterService parameterService;
@InjectMocks
@Autowired
private PriceServiceImpl priceService;
@Before
public void before() {
MockitoAnnotations.initMocks(this);
}
@Test
public void test1() {
...
}
}
如果需要mock靜態(tài)方法兔辅,需要額外引入powerMock:
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.0</version>
<scope>test</scope>
</dependency>
單元測試class的注解替換為:
@RunWith(PowerMockRunner.class) // 告訴JUnit使用PowerMockRunner進(jìn)行測試
@PrepareForTest({FaccAppConfig.class}) // 所有需要測試的類列在此處腊敲,適用于模擬final類或有final, private, static, native方法的類
@PowerMockIgnore({"javax.*.*", "com.sun.*", "org.xml.*", "org.apache.*"}) //為了解決使用powermock后,提示classloader錯(cuò)誤
如果需要配合springboot來起spring環(huán)境幢妄,注解替換為:
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringRunner.class) //RunWith依然是PowerMock兔仰,那這里Delegate委托給spring
@PowerMockIgnore({"javax.*.*", "com.sun.*", "org.xml.*", "org.apache.*"})
@PrepareForTest({FaccAppConfig.class})
@SpringBootTest
于是可以用PowerMockito來mock靜態(tài)方法,when表達(dá)式依然用的Mockito的api:
PowerMockito.mockStatic(FaccAppConfig.class);
Mockito.when(FaccAppConfig.getProperty(Mockito.anyString())).thenReturn("aaabbbccc");
啟動(dòng)@Test測試方法時(shí)報(bào)錯(cuò)蕉鸳,因?yàn)镻owerMockito版本錯(cuò)誤造成乎赴,從1.7.4升級(jí)到2.0.0即可
運(yùn)行測試方法時(shí),因?yàn)樵摲椒ú恍枰猻pring環(huán)境所以直接執(zhí)行完成潮尝,但順帶啟動(dòng)的spring報(bào)錯(cuò):
Caused by: com.caucho.hessian4.HessianException: jar:file:/D:/work/mavenRepository/com/focustech/serialization-hessian2/1.1.0/serialization-hessian2-1.1.0.jar!/META-INF/serialization/hessian/serializers: com.caucho.hessian4.io.RemoteSerializer is invalid because it does not implement com.caucho.hessian4.io.Serializer
at com.caucho.hessian4.io.ContextSerializerFactory.initSerializerFiles(ContextSerializerFactory.java:344)
at com.caucho.hessian4.io.ContextSerializerFactory.init(ContextSerializerFactory.java:261)
at com.caucho.hessian4.io.ContextSerializerFactory.<init>(ContextSerializerFactory.java:105)
at com.caucho.hessian4.io.ContextSerializerFactory.create(ContextSerializerFactory.java:127)
at com.caucho.hessian4.io.ContextSerializerFactory.create(ContextSerializerFactory.java:125)
at com.caucho.hessian4.io.ContextSerializerFactory.create(ContextSerializerFactory.java:125)
at com.caucho.hessian4.io.ContextSerializerFactory.create(ContextSerializerFactory.java:125)
at com.caucho.hessian4.io.SerializerFactory.<init>(SerializerFactory.java:109)
at com.caucho.hessian4.io.SerializerFactory.<init>(SerializerFactory.java:102)
at com.focus.candy.rpc.protocol.serialization.HessianSerialization.<clinit>(HessianSerialization.java:29)
錯(cuò)誤里提到hessian2在META-INF下的配置文件serializers榕吼,文件配置的實(shí)現(xiàn)類和Serializer接口對應(yīng)不上。就是說SPI機(jī)制沒對應(yīng)上勉失,在啟動(dòng)過程中debug關(guān)鍵代碼:
發(fā)現(xiàn)Serializer接口被PowerMock的JavassistMockClassLoader加載羹蚣,實(shí)現(xiàn)類被標(biāo)準(zhǔn)的AppClassLoader加載,所以無法對應(yīng)上乱凿。
想起來需要排除PowerMock盡量不讓加載公共類顽素,在@PowerMockIgnore添上hessian的路徑"com.caucho.*"即可。