[英]Writing unit tests with mocking of static methods in java
我是剛開始編寫測試的新手。 我需要測試的類有一個方法,需要測試:
public String run(final Map<String, Dataset> datasets)
throws ApiException {
final String sourcePath = ElementsUtil.getElementFromDatasets(inputElementNames.get(0), datasets).getValue();
final String destinationPath = ElementsUtil.getElementFromDatasets(inputElementNames.get(1), datasets).getValue();
final File source = new File(sourcePath);
final File destination = new File(destinationPath);
if (source.exists()) {
if (source.isDirectory()) {
final IOFileFilter filter = new WildcardFileFilter(pattern);
final Iterator<File> it = FileUtils.iterateFiles(source, filter, null);
while (it.hasNext()) {
final File file = it.next();
moveFileToDirectory(file, destination);
}
} else {
moveFileToDirectory(source, destination);
}
} else {
LOGGER.error("Source file/folder at path {} doesn't exist.", sourcePath);
}
return "0";
}
起初,由於我對編寫單元測試的知識有限,我的單元測試看起來像這樣:
@Test(description = "Test in case the source is a file.")
public void moveFileTest1() {
// setup
final String fileName = UUID.randomUUID().toString() + ".txt";
final String folderName = UUID.randomUUID().toString();
final Element source = new Element("source", "./" + fileName);
final Element destination = new Element("destination", "./" + folderName);
...
final Path sourcePath = Paths.get(source.getValue());
final Path destinationPath = Paths.get(destination.getValue());
final Path fileDestination = Paths.get(destination.getValue() + "/" + fileName);
try {
Files.createFile(sourcePath);
Files.createDirectory(destinationPath);
// exercise
moveFile.run("", datasets, null);
// verify
Assert.assertEquals(Files.exists(fileDestination), true);
Assert.assertEquals(Files.exists(sourcePath), false);
} catch (ApiException | IOException e) {
LOGGER.error("Exception : ", e);
} finally {
// teardown
try {
Files.deleteIfExists(sourcePath);
} catch (final IOException e) {
LOGGER.error("Exception in teardown: ", e);
}
try {
Files.deleteIfExists(fileDestination);
} catch (IOException e) {
LOGGER.error("Exception in teardown: ", e);
}
try {
Files.deleteIfExists(destinationPath);
} catch (IOException e) {
LOGGER.error("Exception in teardown: ", e);
}
}
}
在閱讀了一些關於單元測試的文章后,我發現我的測試並不完全是測試一個單元,因為我的方法依賴於不同的util方法。 我也發現了關於在測試中模擬對象以及如何模擬一切的知識。 我的問題是:我應該在每個這些util方法/新對象調用等中使用mocking還是有不同的方法? 您將如何測試這段代碼?
你在做什么叫做集成測試。 集成測試是在不對真實數據或在測試本身過程中產生的數據進行任何模擬的情況下測試對象/方法。 集成測試的作用是測試您的設備,設備使用的設備和使用流程。 如果您只想測試您的單元,則應模擬該單元使用的所有其他單元,並創建成功執行或不成功執行這些單元的流程。 這意味着你應該復制一個測試,在這個測試中,一個用過的單元拋出異常/返回一個你不期望作為一個好的值的值(只有它確實可以做到)並返回你期望的值,現在如何工作用。 通常在編寫測試時,您會進行兩種測試,單元測試和集成測試
有一個很好的測試原則,例如“ 不要嘲笑自己不擁有的東西 ”。 什么意思 這意味着你不應該模擬/存儲任何你無法控制的界面,即使這個界面是由你的公司編寫的,而不是由你的團隊編寫的。
但是編寫單元測試,而不是集成測試,你可能想要模擬除正在測試的類之外的所有類? 實際上,這是一個非常棘手的問題。 關於系統設計而不是關於測試的答案更多。 您可以在這里和此處閱讀有關如何解決該問題的信息 。
這對你意味着什么?
正如你提到的ElementsUtil
是由你編寫的,所以這個類應該被嘲笑。 怎么樣? 這取決於您現在正在編寫的遺留代碼或新代碼。 如果您有遺留代碼 - 那么您需要PowerMock ,否則您可能會更改設計並使用ElementsUtil
的實例。
例如,將ElementsUtil
類划分為三個類: Elements
- interface, ElementsImpl
- implementation, ElementsUtil
- 具有靜態訪問權限的類,以保持兼容性。 ElementsUtil
可能有方法
public static Elements getInstance()
並且該方法可以由在構造函數中包含run
方法的類使用。 但是您可以為構造函數提供參數或setter。 順便說一句,我記得Mockito可以將模擬注入到私有字段中。 重構之后,您不需要PowerMock,而只能使用Mockito。
現在關於FileUtils
。 這個班不屬於你,所以如果遵循良好的做法,那么這個班應該是嘲笑的。 但FileUtils
適用於文件,它已經是集成測試。 因此,答案FileUtils
應該由新的類包裝。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.