Spring單元測試私有方法
想要測試某類中的私有方法,必須通過反射。
反射擷取私有方法有兩種方式,一種是直接new對象,然後通過getClass;一種是extends要測試的類,然後this.getClass().getSuperclass()。對于不需要依賴spring容器的私有方法,用上述兩種擷取方式都可以。但是對于依賴bean的私有方法,必須采用extends的方式
原因如下:
new對象的方式不會将該類注入spring容器,故也不會擷取到該類中通過spring容器注入的bean。反映在結果中就是該bean報空指針異常,而用第二種方式的話,由于@RunWith(SpringRunner.class)表示将目前測試類加入spring容器,故可将目前測試類及其超類注入bean。是以使用目前測試類的執行個體就可以擷取到其超類的私有方法,并且通@SpringBootTest擷取到項目中的其他bean
package com.test.impl;
import com.test.ServerApplication.class;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ServerApplication.class)
public class XXXTest extends XXXServiceImpl {
/**
* 測試私有方法示例及說明:
* 想要測試某類中的私有方法,必須通過反射。
* 反射擷取私有方法有兩種方式,一種是直接new對象,然後通過getClass;一種是extends要測試的類,然後this.getClass().getSuperclass()
* 對于不需要依賴spring容器的私有方法,用上述兩種擷取方式都可以。但是對于依賴bean的私有方法,必須采用extends的方式
* 原因如下:
* new對象的方式不會将該類注入spring容器,故也不會擷取到該類中通過spring容器注入的bean。反應在結果中就是該bean報空指針異常
* 而用第二種方式的話,由于@RunWith(SpringRunner.class)表示将目前測試類加入spring容器,故可将目前測試類及其超類注入bean。
* 是以使用目前測試類的執行個體就可以擷取到其超類的私有方法,并且通過@SpringBootTest擷取到項目中的其他bean
*/
@Test
public void xxxTest() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Method method = this.getClass().getSuperclass().getDeclaredMethod("xxx", List.class, Set.class);
method.setAccessible(true);
Object o = method.invoke(this, Collections.singletonList("1111"), new HashSet<>());
}
}