英文:
Junit mocking files using jmockit
问题
我正在尝试第一次使用 jmockit 测试我的 Java 代码,但我感到非常困惑。我有一个方法,它读取文件并将从文件中读取的字符串行作为列表返回。
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Reader {
public static final int LIMIT = -1;
public static final int EMPTY_FILE = 0;
private String delimiter = ",";
public Reader() {}
public List<List<String>> readFile(String fileName, String delimiter) throws IOException {
List<List<String>> rawData = new ArrayList<>();
File input = new File(fileName);
if (!delimiter.isEmpty())
this.delimiter = delimiter;
if (input.length() == EMPTY_FILE) {
throw new IOException("File is empty. Check file and try again.");
}
BufferedReader reader = new BufferedReader(new FileReader(input));
String line;
while ((line = reader.readLine()) != null) {
List<String> lineData = Arrays.asList(line.split(this.delimiter, LIMIT));
rawData.add(lineData);
}
return rawData;
}
}
class ReaderTest {
static final String FILENAME = "input.txt";
@Injectable
File mockedFile;
@Mocked
BufferedReader mockedBufferedReader;
@Mocked
FileReader mockedFileReader;
@Test
void readNonEmptyInputFileShouldDoNothing() throws FileNotFoundException {
new Expectations(File.class) {{
new File(anyString);
result = mockedFile;
}};
new Expectations(BufferedReader.class) {{
new FileReader(anyString);
result = mockedFileReader;
new BufferedReader(mockedFileReader);
result = mockedBufferedReader;
}};
Reader reader = new Reader();
Assertions.assertDoesNotThrow(() ->
reader.readFile(FILENAME, FieldsConstants.DELIMITER));
}
}
该测试代码会导致 IllegalArgumentException 错误:
Invalid Class argument for partial mocking (use a MockUp instead): class java.io.File
英文:
I am trying to test my java code using jmockit for the first time and I am really confused. I have a method that reads a file and returns the line of strings that reads from the file as a list.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Reader {
public static final int LIMIT = -1;
public static final int EMPTY_FILE = 0;
private String delimiter = ",";
public Reader() {}
public List<List<String>> readFile(String fileName, String delimiter) throws IOException {
List<List<String>> rawData = new ArrayList<>();
File input = new File(fileName);
if (!delimiter.isEmpty())
this.delimiter = delimiter;
if (input.length() == EMPTY_FILE) {
throw new IOException("File is empty. Check file and try again.");
}
BufferedReader reader = new BufferedReader(new FileReader(input));
String line;
while ((line = reader.readLine()) != null) {
List<String> lineData = Arrays.asList(line.split(this.delimiter, LIMIT));
rawData.add(lineData);
}
return rawData;
}
}
I am trying to test this code using mocked readers and bufferedReader but without any luck. Obviously I am doing something wrong but I can't figure out how to do it properly.
What I want is to create a mocked file that will be read and test it like its empty or non empty.
What I have tried so far :
class ReaderTest {
static final String FILENAME = "input.txt";
@Injectable
File mockedFile;
@Mocked
BufferedReader mockedBufferedReader;
@Mocked
FileReader mockedFileReader;
@Test
void readNonEmptyInputFileShouldDoNothing() throws FileNotFoundException {
new Expectations(File.class) {{
new File(anyString);
result = mockedFile;
}};
new Expectations(BufferedReader.class) {{
new FileReader(anyString);
result = mockedFileReader;
new BufferedReader(mockedFileReader);
result = mockedBufferedReader;
}};
Reader reader = new Reader();
Assertions.assertDoesNotThrow(() ->
reader.readFile(FILENAME, FieldsConstants.DELIMITER));
}
}
This test gives me an IllegalArgumentException error:
Invalid Class argument for partial mocking (use a MockUp instead): class java.io.File
答案1
得分: 0
我使用了PowerMock和EasyMock API来解决了我的问题。我遇到的唯一问题是,起初我在使用Junit5,而PowerMock的效果不如预期。我切换到Junit4,一切都运行得很好。以下是一些示例代码,如果有兴趣的话:
@RunWith(PowerMockRunner.class)
@PrepareForTest({Reader.class})
@PowerMockIgnore({"javax.management.*", "javax.script.*"})
public class ReaderTest {
public static final String TEST_LINE = "2,Ned,Flanders,SELLER,,,LINE_A,Springfield,12.8,TRUE";
public static final String FILENAME = "file_name";
public static final int LIMIT = -1;
private static List<List<String>> tmpList;
@BeforeClass
public static void beforeAll() {
List<String> tmpLine = Arrays.asList(TEST_LINE.split(FieldsConstants.DELIMITER, LIMIT));
tmpList = new ArrayList<>();
tmpList.add(tmpLine);
}
@Test
public void readNonEmptyInputFileShouldDoNothing() throws Exception {
File mockFile = createMockAndExpectNew(File.class, FILENAME);
FileReader mockFileReader = createMockAndExpectNew(FileReader.class, mockFile);
BufferedReader mockBufferedReader = createMockAndExpectNew(BufferedReader.class, mockFileReader);
Reader reader = new Reader();
expect(mockFile.length()).andReturn((long) 100);
expect(mockBufferedReader.readLine()).andReturn(TEST_LINE);
expect(mockBufferedReader.readLine()).andReturn(null);
replayAll();
assertEquals(reader.readFile(FILENAME, ""), tmpList);
verifyAll();
}
}
英文:
I managed to solve my issue using PowerMock and EasyMock API. The only issue i faced was that in the beginning i was using Junit5 and PowerMock wasn't working as intended. I switched to Junit4 and everything worked out just fine. Just some sample code if anyone is interested:
@RunWith(PowerMockRunner.class)
@PrepareForTest({Reader.class})
@PowerMockIgnore({"javax.management.*", "javax.script.*"})
public class ReaderTest {
public static final String TEST_LINE = "2,Ned,Flanders,SELLER,,,LINE_A,Springfield,12.8,TRUE";
public static final String FILENAME = "file_name";
public static final int LIMIT = -1;
private static List<List<String>> tmpList;
@BeforeClass
public static void beforeAll() {
List<String> tmpLine = Arrays.asList(TEST_LINE.split(FieldsConstants.DELIMITER, LIMIT));
tmpList = new ArrayList<>();
tmpList.add(tmpLine);
}
@Test
public void readNonEmptyInputFileShouldDoNothing() throws Exception {
File mockFile = createMockAndExpectNew(File.class, FILENAME);
FileReader mockFileReader = createMockAndExpectNew(FileReader.class, mockFile);
BufferedReader mockBufferedReader = createMockAndExpectNew(BufferedReader.class, mockFileReader);
Reader reader = new Reader();
expect(mockFile.length()).andReturn((long) 100);
expect(mockBufferedReader.readLine()).andReturn(TEST_LINE);
expect(mockBufferedReader.readLine()).andReturn(null);
replayAll();
assertEquals(reader.readFile(FILENAME, ""), tmpList);
verifyAll();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论