我的实用程序中有一个方法:
public void createDirectories(final Path root, final Scaffolding scaffolding) throws FileAlreadyExistsException {
if (Files.exists(root)) {
throw new FileAlreadyExistsException("Root directory " + root.toString() + " already exists.");
} else {
Files.createDirectories(root);
// Create directories from the scaffolding object
}
}
我想模仿Files
,以便我可以测试以确保调用预期字段Files.createDirectories
。
我可以和Mockito一起做吗?或者我是否需要实际创建目录并检查它们是否存在于某个tmp文件夹中?
答案 0 :(得分:1)
您可以使用JUnit @Rule
来创建一个临时文件夹,在测试执行完成(或失败)后将删除该文件夹:
public class TestTemporaryFolderRule {
@Rule
public TemporaryFolder testFolder = new TemporaryFolder();
@Test
public void testInTempFolder() throws IOException {
File tempFolder = testFolder.newFolder("test");
// test...
}
}
答案 1 :(得分:1)
当你用tdd写东西并遇到麻烦时,将其视为糟糕设计的信号。你不需要模拟静态字段或找到一些棘手的lib来做它。而不是这样做make代表文件系统的实体,并将与文件操作相关的所有方法放在这个类中。有了这个重构,你的代码将是这样的:
class UtilClass { //util classes are bad don't do it
private final FileSystem fileSystem;
public UtilClass(FileSystem fileSystem) {
this.fileSystem = fileSystem;
}
public void createDirectories(final Path root, final Scaffolding scaffolding) throws FileAlreadyExistsException {
if (fileSystem.exists(root)) {
throw new FileAlreadyExistsException("Root directory " + root.toString() + " already exists.");
} else {
fileSystem.createDirectories(root);
// Create directories from the scaffolding object
}
interface FileSystem {
boolean exists(Path path);
void createDirectories(Path path);
}
和测试类
class UtilClassTest {
@Test(expected = FileAlreadyExistsException.class)
public void shouldThrowExceptionWhenRootPathExists() {
FileSystem mockFileSystem = Mockito.mock(FileSystem.class);
Mockito.when(mockFileSystem.exists(anyPath())).return(true);
UtilClass util = new UtilClass(mockFileSystem);
util.createDirectories(mock(Path.class), mock(Scaffolding.class))
}
}
在您的代码外部测试中将mock替换为实现。
class FileSystemImpl implements FileSystem {
boolean exists(Path path){
return Files.exists(path);
}
createDirectories(Path path){
return Files.createDirectories(path);
}
}
并且您不需要在测试或模拟静态字段中触摸文件系统。
答案 2 :(得分:0)
您不能使用基本Mockito模拟静态方法,在大多数情况下,您也不能,尤其是Java提供的方法。您可以使用PowerMock模拟静态方法,但这是一个全局核心库。
您在此处测试的一段代码是,如果目录存在,您是否会收到异常。如果Files.exists()
返回错误结果,则您的程序会以任何方式烘烤。因此,您应该最终测试的是,正在根据完全实现的Files
全局执行流程,正确地遵循流程。
@Test
public void testCreateDirectories() {
File tempFile = new File("test");
tempFile.delete(); //delete test directory if it exists
tempFile.deleteOnExit(); //and again when the test finishes
Path testPath = tempFile.getPath();
foo.createDirectories(testPath, mock(Scaffolding.class)); //should create path
Assert.assertTrue(tempFile.exists());
try {
foo.createDirectories(testPath, mock(Scaffolding.class)); //should FAE
Assert.fail(Should have thrown an FAE exception at this point!);
}
catch(FileAlreadyExistsException faee) {
logger.debug("Expected FAE exception thrown", faee);
}
}
此执行将遍历true和false路径并自行清理。
逻辑的这种双重执行测试两个路径,并且如果您的if
语句设置为混乱,则设计用于涵盖以下方案。