如何测试需要文件的方法?

时间:2017-07-09 10:48:56

标签: java testing junit

我有“密码”这个类。在这个课程中,我有两个公共方法,“setPassword”和“getPassword” 这是代码:

public static void setPassword(String password) throws IOException {

    JSONObject jsonObject = new JSONObject();
    jsonObject.put("password", password);

    FileWriter fileWriter = new FileWriter("data/password/" + User.getCurrentUser() + "_password.json");
    fileWriter.write(jsonObject.toJSONString());
    fileWriter.close();
}

public static String getPassword(String user) throws IOException, ParseException {

    File passwordFile = new File("data/password/" + user.toLowerCase() + "_password.json");

    return readPassword(passwordFile);
}

private static String readPassword(File passwordFile) throws IOException, ParseException {

    JSONParser jsonParser = new JSONParser();
    FileReader fileReader = new FileReader(passwordFile);
    Object object = jsonParser.parse(fileReader);

    JSONObject jsonObject = (JSONObject) object;
    fileReader.close();

    return (String) jsonObject.get("password");
}

如何使用JUnit测试此方法? 我应该使用Mockito框架吗?

2 个答案:

答案 0 :(得分:0)

我不会嘲笑事物,而是重新设计类以使其可测试:

  • 在构造函数中传递文件名
  • 使方法非静态

在您的测试中,您现在可以create a temporary file并将其用于测试。

答案 1 :(得分:0)

我使用了您的示例并找到了基于PowerMock的解决方案。

我尽可能地简化了您的类,只显示了变通方法的关键方面:您将获取密码文件解压缩到包可见方法,然后在测试中模拟此方法:

public class Password {
    public static String getPassword(String user) throws IOException {
        File passwordFile = getPasswordFile(user);
        return readPassword(passwordFile);
    }

    public static void setPassword(String password) throws IOException {
        File passwordFile = getPasswordFile("User.getCurrentUser()");
        writePassword(passwordFile, password);
    }

    static File getPasswordFile(String userName) {
        return new File("data/password/" + userName.toLowerCase() + "_password.json");
    }

    private static String readPassword(File passwordFile) throws IOException {
        // do the reading
        return "actual password";
    }

    private static void writePassword(File passwordFile, String password) {
        // do the saving
    }
}

在测试中,您通过spy()调用部分模拟您的密码类,并用您期望的密码文件替换密码文件:

@RunWith(PowerMockRunner.class)
@PrepareForTest(fullyQualifiedNames = "com.your.domain.Password")
public class PasswordTest {
    @Test
    public void getPassword() throws Exception {
        spy(Password.class);

        final File expectedPasswordFile = new File("some test specific path");
        when(Password.getPasswordFile("bob")).thenReturn(expectedPasswordFile);

        final String actualResult = Password.getPassword("bob");
        Assert.assertEquals("expected result", actualResult);
    }
}

这种方式的缺点:单元测试不包括你的getPasswordFile()。

可能是我错过了一些你的项目具体细节,但我希望你的想法很清楚。