Como esse código do SwingWorker pode ser testado

Considere este código:

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 é um JTextField e 'creator' é uma interface injetada para gravar o arquivo (para que a parte esteja sob teste). O local em que o arquivo foi gravado é codificado de propósito, porque é um exemplo. E o java.util.logging é usado simplesmente para evitar uma dependência externa.

Como você classificaria isso para torná-lo testável por unidade (incluindo abandonar o SwingWorker, se necessário, mas depois substituir sua funcionalidade, pelo menos como usado aqui).

Na minha opinião, o doInBackground está basicamente bem. A mecânica fundamental é criar um escritor e fechá-lo, o que é muito simples de testar e o trabalho real está sendo testado. No entanto, o método done é problemático entre aspas, incluindo seu acoplamento com o método actionPerformed à classe pai e coordenando a ativação e desativação do botão.

No entanto, separar isso não é óbvio. A injeção de algum tipo de SwingWorkerFactory torna muito mais difícil a captura dos campos da GUI (é difícil ver como isso seria uma melhoria no design). O JOpitonPane e o Desktop têm toda a "bondade" dos Singletons, e o tratamento de exceções torna impossível envolver a obtenção facilmente.

Então, qual seria uma boa solução para colocar esse código em teste?

questionAnswers(3)

yourAnswerToTheQuestion