我有以下示例单元测试试图模拟java.nio.file.Files但这个模拟不起作用,代码试图删除示例路径。
@Test
public void testPostVisitDirectory() throws Exception {
Path mockedPath = Paths.get("sample path");
PowerMockito.mockStatic(Files.class);
PowerMockito.doNothing().when(Files.class,
PowerMockito.method(Files.class, "delete", Path.class));
DeleteDirVisitor visitor = new DeleteDirVisitor(false);
Assert.assertEquals("The was a problem visiting the file",
FileVisitResult.CONTINUE,
visitor.postVisitDirectory(mockedPath, null));
}
知道出了什么问题吗?
这是方法visitor.postVisitDirectory
[...]
if (e == null) {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
[...]
谢谢,
答案 0 :(得分:4)
你添加了
吗?@RunWith(PowerMockRunner.class)
@PrepareForTest(Files.class)
到包含该方法的junit测试类?
参见powermock docs,写作测试部分。
修改强>
嗯,看起来你做的一切都很正确。这就是我正在运行的:import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest(Files.class)
public class TestVisitor {
public class PrintingVisitor extends SimpleFileVisitor<Path> {
@Override
public FileVisitResult postVisitDirectory(final Path dir, final IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
}
@Test
public void testPostVisitDirectory() throws Exception {
final Path mockedPath = Paths.get("sample path");
/* Mocking */
PowerMockito.mockStatic(Files.class);
PowerMockito.doNothing().when(Files.class, PowerMockito.method(Files.class, "delete", Path.class));
/* End Mocking */
final PrintingVisitor visitor = new PrintingVisitor();
Assert.assertEquals("The was a problem visiting the file", FileVisitResult.CONTINUE, visitor.postVisitDirectory(mockedPath, null));
}
}
如果我注释掉标记为Mocking的部分,我会得到NoSuchFileException
。如果我离开它,测试通过。
也许发布产生错误的完整示例?
答案 1 :(得分:4)
我有一个类似的问题,使用powermock 1.5.1和Files类,并怀疑它有一个问题静态模拟一些/所有jdk1.7类,虽然我不知道为什么。我还检查了javassist版本,当时它是最新的(3.18.0-GA),
我将测试中的课程剥离到了“文件”行,但仍然无法正常工作。然后我决定尝试模拟另一个静态类StringUtils.chop(“string”); (commons-lang3)然后我的powermock测试工作,我能够强制它从模拟生成异常。
这证明了我已经完成了本书的所有内容,并且静态模拟在Files类上不起作用,但它在StringUtils上完成。
顺便说一下,我改变了@PrepareForTest和PowerMockito.mockStatic()调用引用正确的类。
最后我放弃了嘲弄文件。如果其他人遇到同样的问题,只需要提醒。
修改。搞定了:我已经尝试了这个,因为我在另一个项目中需要它。还有更新版本的PowerMock out(1.5.3),它使用更新的javassist(3.18.1-GA)来修复我在回复另一条评论时提到的错误。
即使您正在测试的类没有公开静态方法,我也可以通过将测试中的类添加到Files
以及@PrepareForTest
来不断地模拟Files
。对于其他静态模拟,我之前不需要这样做。我不知道为什么它需要或以Files
的方式工作。
示例:
public class MyTestClass {
public void justToTestMocking(Path path) throws IOException {
if (!Files.exists(path)) {
throw new IllegalArgumentException("I know there is a deleteIfExists() but I am just testing mocking");
}
Files.delete(path);
}
}
以下测试:
@RunWith(PowerMockRunner.class)
@PrepareForTest({Files.class, MyTestClass.class})
public class MyTestClassTest {
@Before
public void setUp() {
mockStatic(Files.class);
}
@Test
public void justToTestMocking_WillDeletePath() throws IOException {
Path path = mock(Path.class);
MyTestClass test = new MyTestClass();
when(Files.exists(path)).thenReturn(true);
test.justToTestMocking(path);
verifyStatic();
Files.delete(path);
}
}
答案 2 :(得分:1)
我遇到了类似的问题,结果发现它与准备正确的课程有关。
在上面的示例中,测试的类已经在“prepareFor-Scope”中,因为它是测试类的内部类。
你必须将类添加到调用静态方法的@PrepareForTest
...在我的情况下这些是不够的,因为访问Files.delete
的代码是在一个无法明确的匿名类中的准备。
我将匿名类命名为@PrepareForTest
,并且一切正常