I have a java swing application which expects the users to choose YES
or NO
from JOptionPane.showConfirmDialog
Since the JOptionPane stops the thread and is waiting for user input, my code is not automatically testable.
Is there anyway I can programatically get around this? Or simulate yes or no?
In my test now, a confirm dialog appears, where I have to push the yes or no button.
Update
I found a brilliant option.
I created an interface called OptionPane
with basically all the different types of messages I need.
Then I created a default implementation that just relegates to the JOptionPane`s static methods. Then I created a YesMockOptionPane, that basically returns YES_OPTION for all the confirm messages, and a NoMockOptionPane for all the NO_OPTIONS.
Here is the code:
<<usage>>
class Foo {
OptionPane optionPane = new DefaultOptionPane();
public void someMethod() {
if (optionPane.showConfirmDialog(null, "choose yes or no", "Please confirm",
JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION)
return;
//User pressed yes
}
public void setOptionPane(OptionPane o) {
this.optionPane = o;
}
}
//Snippet of the interface
public interface OptionPane {
int showConfirmDialog(Component parentComponent,
Object message, String title, int optionType);
}
public class DefaultOptionPane implements OptionPane {
@Override
public int showConfirmDialog(Component parentComponent,
Object message, String title, int optionType) {
return JOptionPane.showConfirmDialog(parentComponent,message,title,optionType);
}
}
public class YesMockOptionPane extends DefaultOptionPane {
//MockOptionPane is just an abstract class implementing default methods from OptionPane
@Override
public int showConfirmDialog(Component parentComponent, Object message, String title, int optionType) {
return JOptionPane.YES_OPTION;
}
}
Now in the unit test I can simply set the appropriate MockOptionPane.
dialog.setOptionPane(new YesMockOptionPane());
This is the solution I came up with (also copied in the question)
<<usage>>
class Foo {
OptionPane optionPane = new DefaultOptionPane();
public void someMethod() {
if (optionPane.showConfirmDialog(null, "choose yes or no", "Please confirm",
JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION)
return;
//User pressed yes
}
public void setOptionPane(OptionPane o) {
this.optionPane = o;
}
}
//Snippet of the interface
public interface OptionPane {
int showConfirmDialog(Component parentComponent,
Object message, String title, int optionType);
}
public class DefaultOptionPane implements OptionPane {
@Override
public int showConfirmDialog(Component parentComponent,
Object message, String title, int optionType) {
return JOptionPane.showConfirmDialog(parentComponent,message,title,optionType);
}
}
public class YesMockOptionPane extends MockOptionPane {
@Override
public int showConfirmDialog(Component parentComponent, Object message, String title, int optionType) {
return JOptionPane.YES_OPTION;
}
}
Now in the unit test I can simply set the appropriate MockOptionPane.
dialog.setOptionPane(new YesMockOptionPane());