diesen Code vor:Wie kann dieser Code Swingworker gemacht wird prüfbar
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
ein JTextField ist und ‚Schöpfer‘ ist eine injizierte Schnittstelle zum Schreiben der Datei (so dass ein Teil ist im Test). Der Ort, an dem die Datei geschrieben wird, ist absichtlich hart codiert, da dies als Beispiel dienen soll. Und java.util.logging wird einfach verwendet, um eine externe Abhängigkeit zu vermeiden.
Wie würden Sie das aufteilen, um es unitestfähig zu machen (einschließlich des Verzichts auf SwingWorker bei Bedarf, aber dann Ersetzen seiner Funktionalität, zumindest wie hier verwendet).
So wie ich es sehe, ist der doInBackground grundsätzlich in Ordnung. Die grundlegenden Mechanismen erstellen einen Schreiber und schließen ihn, was fast zu einfach zu testen ist und die wirkliche Arbeit wird getestet. Die done-Methode ist jedoch problematisch, einschließlich ihrer Kopplung mit der actionPerformed-Methode der übergeordneten Klasse und der Koordination der Aktivierung und Deaktivierung der Schaltfläche.
Allerdings ist das Auseinanderziehen nicht offensichtlich. Durch das Einfügen einer Art von SwingWorkerFactory ist es viel schwieriger, die GUI-Felder zu erfassen (es ist schwer zu erkennen, wie dies eine Designverbesserung wäre). Das JOpitonPane und der Desktop haben alle die "Güte" von Singletons, und die Ausnahmebehandlung macht es unmöglich, das Get einfach zu verpacken.
Also, was wäre eine gute Lösung, um diesen Code unter Test zu bringen?
Umformatierter Code; Bitte zurück, wenn nicht korrekt. – trashgod
Keine vollständige Antwort: Aber wenn Sie Qualitätscode mögen, gehen Sie nicht in die Nähe von 'SwingWorker'. Im Allgemeinen Faktoren aus. Wo Sie eine API haben, die Statik/Singletons verwendet, führen Sie eine Schnittstelle mit einer Implementierung ein, die die "echte" statische API verwendet, und eine andere für das Spotten (möglicherweise eine andere für das Auditing). –
@Tom, wenn Sie Zeit haben, den Entwurf eines alternativen Entwurfs zu SwingWorker zu schreiben (oder wenn Sie von einer alternativen besseren Implementierung wissen) würde es sehr geschätzt werden. – Yishai