我是初次编写测试的新手。我需要测试的类有一个方法,需要进行测试:
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还是有不同的方法?你会如何测试这段代码?
答案 0 :(得分:0)
您正在做的事情称为集成测试。集成测试是测试一个对象/方法,而不会在测试本身产生的实际数据或数据上进行任何模拟。集成测试的作用是测试您的设备,设备使用的设备和使用流程。如果您只想测试您的单位,您应该模拟您的单位使用的所有其他单位,并创建那些单位成功完成工作的流程。这意味着你应该复制一个测试,其中一个用过的单位抛出一个异常/返回一个你不希望作为一个好的值的值(只有它确实可以做到)并返回你期望的值,现在如何跟...共事。 通常在编写测试时,您会进行两种测试,单元测试和集成测试
答案 1 :(得分:0)
有一个很好的测试原则,如“不要嘲笑你不拥有的东西”。这不是什么意思?这意味着你不应该模拟/存储任何你无法控制的界面,即使这个界面是由你的公司编写的,而不是由你的团队编写的。
但是编写单元测试,而不是集成测试,你可能想要模拟除正在测试的类之外的所有类?实际上,这是一个非常棘手的问题。关于系统设计而不是关于测试的答案更多。您可以阅读有关如何解决问题here和here的信息。
这对你意味着什么?
正如你提到的那样0.496899361 30.42497045
已经写好了,所以这个类应该被嘲笑。怎么样?这取决于您现在正在编写的遗留代码或新代码。如果您有遗留代码 - 那么您需要PowerMock,否则您可能会更改设计并使用socket
的实例。
例如,将ElementsUtil
类划分为三个类:ElementsUtil
- 接口,ElementsUtil
- 实现,Elements
- 具有静态访问权限的类以保持兼容性。 ElementsImpl
可能有方法
ElementsUtil
该方法可以由构造函数中包含ElementsUtil
方法的类使用。但是您可以为构造函数提供参数或setter。顺便说一句,我记得Mockito可以把嘲笑注入私人田地。在重构之后,您不需要PowerMock,只能使用Mockito。
现在关于public static Elements getInstance()
。这个班不属于你,所以如果遵循良好的做法,那么这个班应该是嘲笑的。但run
适用于文件,它已经是集成测试。所以回答 - FileUtils
应该由你的新课程包装。