天天看點

Spring單元測試001-如何測試私有方法

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<>());
    }
}