Рассмотрим этот код:
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, а "создатель" - это инъецируемый интерфейс для записи файла (так что эта часть находится под тестированием). Место, где записан файл, жестко закодировано, потому что это предназначено в качестве примера. И java.util.logging используется просто, чтобы избежать внешней зависимости.
Как бы вы это сделали, чтобы сделать его единым для тестирования (в том числе отказаться от SwingWorker, если необходимо, но затем заменить его функциональность, по крайней мере, как используется здесь).
Как я смотрю на это, doInBackground в основном в порядке. Фундаментальная механика создает писателя и закрывает его, что почти слишком просто для тестирования, и настоящая работа находится под контролем. Тем не менее, выполненный метод представляет собой проблему с цитатой, в том числе ее связь с методом actionPerformed с родительским классом и координацию включения и отключения кнопки.
Однако разделить это не очевидно. Внедрение какого-то SwingWorkerFactory делает захват полей GUI намного сложнее в обслуживании (трудно понять, как это будет улучшение дизайна). JOpitonPane и Desktop имеют всю "доброту" синглтонов, а обработка исключений делает невозможным упрощение переноса.
Итак, что было бы хорошим решением для тестирования этого кода?