Spring實現類私有方法測試通用方案

2021-09-10 09:41:53 字數 2522 閱讀 3836

現實的業務場景中,可能需要對spring的實現類的私有方法進行測試。

場景描述:

比如***service裡有 兩個函式a、函式b。

而實現類***serviceimpl中實現了函式a、函式b,還包含私有方法函式c和函式d。

要寫乙個***testcontroller來呼叫***serviceimpl的函式c。

面臨幾個問題:

1、如果注入介面,則無法呼叫實現類的私有類。

2、如果注入實現類,則需要將實現類裡的私有方法改為公有的,而且需要設定@enableaspectjautoproxy(proxytargetclass = true)使用cglib**方式

如果單純為了測試而介面中定義實現類的私有方法或者為了測試而將私有方法臨時改為公有方法,顯然不太合適。

解決方案:

那麼如何解決這個問題呢?是否可以封裝乙個通用的解決方案呢?

可以通過cglib注入實現類的子類,如果是gradle專案也可以使用aspect外掛程式將切面**在編譯器織入實現類中注入的型別則為實現類,然後通過反射設定為可訪問來呼叫私有方法。

下面是我的解決方案

另外還有乙個更好的開源工具 powermock 感興趣的同學可以研究一下

反射呼叫**:

beaninvokeutil

public class beaninvokeutil 

public invokeparams(object object, string methodname, class<?> paramtypes, object args)

public string getmethodname()

public void setmethodname(string methodname)

public class<?> getparamtypes()

public void setparamtypes(class<?> paramtypes)

public object getobject()

public void setobject(object object)

public object getargs()

public void setargs(object args)

} public static object invokeprivatemethod(invokeparams invokeparams) throws invocationtargetexception, illegalacces***ception

private static object doinvoke(invokeparams invokeparams) throws invocationtargetexception, illegalacces***ception else

method.setaccessible(true);

if (args == null)

return method.invoke(object, args);

} private static void checkparams(invokeparams invokeparams)

string methodname = invokeparams.getmethodname();

if (stringutils.isempty(methodname))

// 引數型別陣列和引數陣列要對應

class<?> paramtypes = invokeparams.getparamtypes();

object args = invokeparams.getargs();

boolean illegal = true;

if (paramtypes == null && args != null)

if (args == null && paramtypes != null)

if (paramtypes != null && args != null && paramtypes.length != args.length)

if (!illegal)

}}

使用方式:

使用時通過cglib方式注入實現類或者將切面**編譯器織入實現類的方式,然後注入bean。

@autowired private ***service ***service;
然後填入呼叫的物件,待呼叫的私有方法,引數型別陣列和引數陣列。

beaninvokeutil.invokeprivatemethod(new beaninvokeutil()

.new invokeparams(***service, "someprivatemethod", null, null));

注意這時注入的***service的型別為 ***serviceimpl。

如果需要返回值,可以獲取該呼叫方法的返回值。

使用Junit 測試私有方法

在junit4中如何測試私有方法呢?有如下類和方法 public class printablecharacterascii line 72 r line 73 n return line 此類實現列印 abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstu...

使用Junit 測試私有方法

在junit4中如何測試私有方法呢?有如下類和方法 public class printablecharacterascii line 72 r line 73 n return line 此類實現列印 abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstu...

使用Junit 測試私有方法

在junit4中如何測試私有方法呢?有如下類和方法 public class printablecharacterascii line 72 r line 73 n return line 此類實現列印 abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstu...