如何單元測試Java的private方法

巨輪發表於2020-12-19

問題

Java類中private方法通常只能被其所屬類的呼叫,其他類只能望而卻步,單元測試private方法也就一籌莫展。

嘗試解法:

  1. 在測試時,手動將private改為public,測試完後再將其改回。
  2. 將測試方法寫進private方法的所屬類中,這樣就能呼叫private方法了。

上述解法雖然可行,但這些解法或多或少地違背單元測試應遵守AIR原則。

單元測試線上上執行時,感覺像空氣(AIR)那樣透明,但在測試質量的保障上,卻是非常關鍵的。好的單元測試巨集觀上來說,具有自動化、獨立性、可重複執行的特點。

  • A:Automatic(自動化)
  • I:Independent(獨立性)
  • R:Repeatable(可重複)

解法

我們可以用Java的反射特性來突破private的限制,從而對private方法進行單元測試:

測試目標類:

public class App {

	public void doSomething() {
		callPrivateMethod();
	}
	
	
	private String callPrivateMethod() {
		return "Private method is called.";
	}
	
}

單元測試程式碼:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.junit.Assert;
import org.junit.Test;

public class AppTest {

	@Test
	public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		App app = new App();
		
		Method privateMethod = app.getClass().getDeclaredMethod("callPrivateMethod");
		privateMethod.setAccessible(true);
		
		Assert.assertEquals("Private method is called.", privateMethod.invoke(app));
	}
}

參考

  1. Junit測試private方法
  2. 阿里巴巴Java開發手冊

相關文章