Junit 使用 jmockit 模拟文件

Junit mocking files using jmockit

我第一次尝试使用 jmockit 测试我的 java 代码,我真的很困惑。我有一个读取文件的方法,returns 从文件中读取的字符串行作为列表。

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;
    }
}

我正在尝试使用模拟阅读器和 bufferedReader 测试此代码,但没有任何运气。显然我做错了什么,但我不知道如何正确地做。

我想要的是创建一个模拟文件,它将被读取并测试它是否为空或非空。

到目前为止我尝试了什么:

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

我设法使用 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();
    }
}