常規(guī)的單元測(cè)試只需要引入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>
單元測(cè)試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>
單元測(cè)試class的注解替換為:
@RunWith(PowerMockRunner.class) // 告訴JUnit使用PowerMockRunner進(jìn)行測(cè)試
@PrepareForTest({FaccAppConfig.class}) // 所有需要測(cè)試的類列在此處,適用于模擬final類或有final, private, static, native方法的類
@PowerMockIgnore({"javax.*.*", "com.sun.*", "org.xml.*", "org.apache.*"}) //為了解決使用powermock后,提示classloader錯(cuò)誤
如果需要配合springboot來(lái)起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來(lái)mock靜態(tài)方法,when表達(dá)式依然用的Mockito的api:
PowerMockito.mockStatic(FaccAppConfig.class);
Mockito.when(FaccAppConfig.getProperty(Mockito.anyString())).thenReturn("aaabbbccc");
啟動(dòng)@Test測(cè)試方法時(shí)報(bào)錯(cuò),因?yàn)镻owerMockito版本錯(cuò)誤造成,從1.7.4升級(jí)到2.0.0即可

運(yùn)行測(cè)試方法時(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接口對(duì)應(yīng)不上。就是說(shuō)SPI機(jī)制沒對(duì)應(yīng)上,在啟動(dòng)過(guò)程中debug關(guān)鍵代碼:



發(fā)現(xiàn)Serializer接口被PowerMock的JavassistMockClassLoader加載,實(shí)現(xiàn)類被標(biāo)準(zhǔn)的AppClassLoader加載,所以無(wú)法對(duì)應(yīng)上。
想起來(lái)需要排除PowerMock盡量不讓加載公共類,在@PowerMockIgnore添上hessian的路徑"com.caucho.*"即可。