我想介绍一个用单元测试创建文件的逻辑。是否可以模拟File类并避免实际创建文件?
答案 0 :(得分:7)
模拟构造函数,就像在这个示例代码中一样。 不要忘记在 @PrepareForTest
中放置将调用“新文件(...)”的类package hello.easymock.constructor;
import java.io.File;
import org.easymock.EasyMock;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest({File.class})
public class ConstructorExampleTest {
@Test
public void testMockFile() throws Exception {
// first, create a mock for File
final File fileMock = EasyMock.createMock(File.class);
EasyMock.expect(fileMock.getAbsolutePath()).andReturn("/my/fake/file/path");
EasyMock.replay(fileMock);
// then return the mocked object if the constructor is invoked
Class<?>[] parameterTypes = new Class[] { String.class };
PowerMock.expectNew(File.class, parameterTypes , EasyMock.isA(String.class)).andReturn(fileMock);
PowerMock.replay(File.class);
// try constructing a real File and check if the mock kicked in
final String mockedFilePath = new File("/real/path/for/file").getAbsolutePath();
Assert.assertEquals("/my/fake/file/path", mockedFilePath);
}
}
答案 1 :(得分:6)
我不确定是否可能,但我有这样的要求,我通过创建FileService
接口解决了这个问题。因此,不是直接创建/访问文件,而是添加抽象。然后,您可以在测试中轻松模拟此界面。
例如:
public interface FileService {
InputStream openFile(String path);
OutputStream createFile(String path);
}
然后在你的课堂上使用这个:
public class MyClass {
private FileService fileService;
public MyClass(FileService fileService) {
this.fileService = fileService;
}
public void doSomething() {
// Instead of creating file, use file service
OutputStream out = fileService.createFile(myFileName);
}
}
在你的考试中
@Test
public void testOperationThatCreatesFile() {
MyClass myClass = new MyClass(mockFileService);
// Do your tests
}
这样,您甚至可以在没有任何模拟库的情况下进行模拟。
答案 2 :(得分:6)
尝试PowerMockito
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
@PrepareForTest(YourUtilityClassWhereFileIsCreated.class)
public class TestClass {
@Test
public void myTestMethod() {
File myFile = PowerMockito.mock(File.class);
PowerMockito.whenNew(File.class).withAnyArguments().thenReturn(myFile);
Mockito.when(myFile.createNewFile()).thenReturn(true);
}
}