Java 使用Mockito/PowerMockito在没有现有文件的情况下模拟FileInputStream
我正在为使用Java 使用Mockito/PowerMockito在没有现有文件的情况下模拟FileInputStream,java,junit,mockito,powermockito,Java,Junit,Mockito,Powermockito,我正在为使用FileInputStream的方法编写JUnit,并且在构造函数中只传递文件名。该文件是作为servlet请求的一部分创建的,并且该文件不会存储在任何位置 我正在尝试使用PowerMockito模拟FileInputStream,以便它给我一个模拟文件对象。不幸的是,我得到了有效的FileNotFoundException,但我不确定如何测试该方法,因为该文件不存在 试验方法: public String viewReport() throws Exception { th
FileInputStream
的方法编写JUnit
,并且在构造函数中只传递文件名。该文件是作为servlet请求的一部分创建的,并且该文件不会存储在任何位置
我正在尝试使用PowerMockito
模拟FileInputStream
,以便它给我一个模拟文件对象。不幸的是,我得到了有效的FileNotFoundException
,但我不确定如何测试该方法,因为该文件不存在
试验方法:
public String viewReport() throws Exception {
this.inputStream = new FileInputStream(DOCUSIGN_REPORT_FILE);
try {
boolean returnReport = validateRequest();
if (returnReport) {
intgList = this.generateViewIntegrationReportData(getESignUIConfig());
this.createCSVFile(intgList, new FileWriter(DOCUSIGN_REPORT_FILE));
} else {
failureResponse(msgs, 400);
return null;
}
} catch (Exception e) {
e.printStackTrace();
msgs.add(new Message(ESignatureIntegrationMessageTypeEnum.MESSAGE_TYPE_ERROR,
UiIntegrationKeyConstants.UI_INTEGRATION_ERROR_CODE_500, UiIntegrationKeyConstants.UI_INTEGRATION_ERROR_TEXT_SERVICE_ERROR));
failureResponse(msgs, 500);
return null;
}
return UiIntegrationKeyConstants.REPORT_REPSONSE;
}
JUnit测试到目前为止
@Test
public void testViewReport() throws Exception {
Map<String, Object> actionMap = new HashMap<>();
actionMap.put("application", "ESignatureIntegrationAction");
ActionContext.setContext(new ActionContext(actionMap));
FileInputStream inputStream = Mockito.mock(FileInputStream.class);
PowerMockito.whenNew(FileInputStream.class).withAnyArguments().thenReturn(inputStream);
action = new ESignatureIntegrationAction();
action.viewReport();
}
@测试
public void testViewReport()引发异常{
Map actionMap=newhashmap();
actionMap.put(“应用程序”、“ESignatureIntegrationAction”);
setContext(新的ActionContext(actionMap));
FileInputStream-inputStream=Mockito.mock(FileInputStream.class);
PowerMockito.whenNew(FileInputStream.class).withAnyArguments().thenReturn(inputStream);
action=新的ESignatureIntegrationAction();
action.viewReport();
}
当代码到达新文件inputstream(DOCUSIGN\u REPORT\u文件)时,我得到一个异常
代码>
谢谢您的帮助。我建议您重构代码,使测试无需模拟框架
它可能看起来有点像这样:
public class YourClass {
// ...
public String viewReport() {
try {
boolean isValidRequest = validateRequest();
if (isValidRequest) {
IntegrationReportCsvFileHandler fileHandler = new IntegrationReportCsvFileHandler();
IntegrationReportData inputData = fileHandler.readData(new FileInputStream(DOCUSIGN_REPORT_FILE));
IntegrationReportGenerator generator = new IntegrationReportGenerator();
IntegrationReportData outputData = generator.processData(inputData, getESignUIConfig());
fileHandler.writeReport(outputData, new FileWriter(DOCUSIGN_REPORT_FILE));
} else {
failureResponse(msgs, 400);
return UiIntegrationKeyConstants.FAILURE_RESPONSE;
}
} catch (Exception e) {
e.printStackTrace();
msgs.add(new Message(ESignatureIntegrationMessageTypeEnum.MESSAGE_TYPE_ERROR,
UiIntegrationKeyConstants.UI_INTEGRATION_ERROR_CODE_500, UiIntegrationKeyConstants.UI_INTEGRATION_ERROR_TEXT_SERVICE_ERROR));
failureResponse(msgs, 500);
return UiIntegrationKeyConstants.FAILURE_RESPONSE;
}
return UiIntegrationKeyConstants.REPORT_RESPONSE;
}
// ...
}
public class IntegrationReportData {
// your custom data structure
// may as well just be a List<Data>
// may be different for input and output
}
public class IntegrationReportException extends Exception {
// your custom exception
public IntegrationReportException(String message) { super(exception); }
}
public class IntegrationReportGenerator {
public IntegrationReportData processData(IntegrationReportData data, ESignConfig config) throws IntegrationReportException {
// here's your logic that requires testing
}
}
public class IntegrationReportCsvFileHandler {
public IntegrationReportData readData(InputStream input) throws IOException {
// read data from given input stream
}
public void writeData(IntegrationReportData data, OutputStreamWriter outputWriter) throws IOException {
// write data to given output stream
}
}
公共类您的类{
// ...
公共字符串viewReport(){
试一试{
布尔值isValidRequest=validateRequest();
如果(isValidRequest){
IntegrationReportCsvFileHandler fileHandler=新的IntegrationReportCsvFileHandler();
IntegrationReportData inputData=fileHandler.readData(新的FileInputStream(DOCUSIGN_报告_文件));
IntegrationReportGenerator=新的IntegrationReportGenerator();
IntegrationReportData outputData=generator.processData(inputData,getESignUIConfig());
writeReport(outputData,新的FileWriter(DOCUSIGN_REPORT_FILE));
}否则{
故障响应(msgs,400);
返回UiIntegrationKeyConstants.FAILURE\u响应;
}
}捕获(例外e){
e、 printStackTrace();
msgs.add(新消息(ESignatureIntegrationMessageTypeEnum.Message_TYPE_错误,
UiIntegrationKeyConstants.UI_集成_错误_代码_500,UiIntegrationKeyConstants.UI_集成_错误_文本_服务_错误));
故障响应(msgs,500);
返回UiIntegrationKeyConstants.FAILURE\u响应;
}
返回UiIntegrationKeyConstants.REPORT\u响应;
}
// ...
}
公共类IntegrationReportData{
//您的自定义数据结构
//也可能只是一张清单
//输入和输出可能不同
}
公共类IntegrationReportException扩展了异常{
//您的自定义异常
公共集成报告异常(字符串消息){super(异常);}
}
公共类IntegrationReportGenerator{
公共IntegrationReportData processData(IntegrationReportData数据,ESignConfig配置)引发IntegrationReportException{
//这是需要测试的逻辑
}
}
公共类IntegrationReportCsvFileHandler{
公共集成报告数据读取数据(InputStream输入)引发IOException{
//从给定的输入流读取数据
}
public void writeData(IntegrationReportData数据,OutputStreamWriter outputWriter)引发IOException{
//将数据写入给定的输出流
}
}
这样,IntegrationReportGenerator
就可以很容易地进行测试。通常的警告:如果要使用工厂(以及依赖项注入)。。。那么您就不需要Powermock来模拟对new的调用。您的意思是我应该使用Spring注入FileInputStream?如果没有代码可以读取的文件,您的测试实际上会测试什么?所以这个方法是Struts2操作,它将此文件作为CSV文件下载。我知道我无法测试CSV的内容,这就是我试图模拟文件创建部分的原因。这段“代码”中的每一行都是错误设计的尖叫。没有必要对这个函数进行单元测试,因为这样的函数是不存在的。