Junit使用jmockit进行文件模拟

huangapple go评论79阅读模式
英文:

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 = &quot;,&quot;;

	
	public Reader() {}

	public List&lt;List&lt;String&gt;&gt; readFile(String fileName, String delimiter) throws IOException {
		List&lt;List&lt;String&gt;&gt; rawData = new ArrayList&lt;&gt;();

		File input = new File(fileName);

		if (!delimiter.isEmpty())
			this.delimiter = delimiter;

		if (input.length() == EMPTY_FILE) {
			throw new IOException(&quot;File is empty. Check file and try again.&quot;);
		}

		BufferedReader reader = new BufferedReader(new FileReader(input));

		String line;

		while ((line = reader.readLine()) != null) {
			List&lt;String&gt; 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 = &quot;input.txt&quot;;

	@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(() -&gt;
				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({&quot;javax.management.*&quot;, &quot;javax.script.*&quot;})
public class ReaderTest {
	public static final String TEST_LINE = &quot;2,Ned,Flanders,SELLER,,,LINE_A,Springfield,12.8,TRUE&quot;;
	public static final String FILENAME = &quot;file_name&quot;;
	public static final int LIMIT = -1;

	private static List&lt;List&lt;String&gt;&gt; tmpList;

	@BeforeClass
	public static void beforeAll() {
		List&lt;String&gt; tmpLine = Arrays.asList(TEST_LINE.split(FieldsConstants.DELIMITER, LIMIT));
		tmpList = new ArrayList&lt;&gt;();
		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, &quot;&quot;), tmpList);
		verifyAll();
	}
}

huangapple
  • 本文由 发表于 2020年8月25日 20:11:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/63578585.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定