如何使这个SwingWorker代码可测试
请考虑以下代码:
public void actionPerformed(ActionEvent e) {
setEnabled(false);
new SwingWorker<File, Void>() {
private String location = url.getText();
@Override
protected File doInBackground() throws Exception {
File file = new File("out.txt");
Writer writer = null;
try {
writer = new FileWriter(file);
creator.write(location, writer);
} finally {
if (writer != null) {
writer.close();
}
}
return file;
}
@Override
protected void done() {
setEnabled(true);
try {
File file = get();
JOptionPane.showMessageDialog(FileInputFrame.this,
"File has been retrieved and saved to:\n"
+ file.getAbsolutePath());
Desktop.getDesktop().open(file);
} catch (InterruptedException ex) {
logger.log(Level.INFO, "Thread interupted, process aborting.", ex);
Thread.currentThread().interrupt();
} catch (ExecutionException ex) {
Throwable cause = ex.getCause() == null ? ex : ex.getCause();
logger.log(Level.SEVERE, "An exception occurred that was "
+ "not supposed to happen.", cause);
JOptionPane.showMessageDialog(FileInputFrame.this, "Error: "
+ cause.getClass().getSimpleName() + " "
+ cause.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
} catch (IOException ex) {
logger.log(Level.INFO, "Unable to open file for viewing.", ex);
}
}
}.execute();
url
是一个JTextField,“creator”是一个用于写入文件的注入接口(因此该部分正在测试中)。写入文件的位置是有意硬编码的,因为这是一个示例。java.util.logging只是为了避免外部依赖。
你如何将其放大以使其可进行单元测试(包括在需要时放弃SwingWorker,但随后替换其功能,至少在这里使用)。
在我看来,doInBackground基本上没问题。基本机制是创建一个编写器并关闭它,这几乎太简单了,无法测试,并且实际工作正在测试中。但是,done 方法在引用时存在问题,包括它与父类的 actionPerform 方法的耦合,以及协调按钮的启用和禁用。
然而,将其分开并不明显。注入某种SwingWorkerFactory使得捕获GUI字段变得更加难以维护(很难看出它将如何进行设计改进)。JOpitonPane 和桌面具有单例的所有“优点”,异常处理使得无法轻松包装 get。
那么,测试此代码的好解决方案是什么呢?