JUnit预期异常未按预期工作

时间:2018-07-20 06:58:27

标签: java junit

我正在尝试在ActionListener中测试私有方法。如果传递了无效的网址,则该方法应引发异常: 这是我测试的代码:

@Rule
public ExpectedException expectedException = ExpectedException.none();
Map<JLabel, JTextField> inputs;
ActionListener listener;
AddStationWindow window;
ArrayList<Station> stationsToDelete;

@Before
public void setUp() throws IllegalAccessException, NoSuchFieldException, 
InstantiationException, SQLException, ClassNotFoundException {
inputs = new HashMap<JLabel, JTextField>();
window = new AddStationWindow();
stationsToDelete = new ArrayList<>();
InitializeH2Database.initialiteDatabase();

}

@Test
public void saveStation() throws NoSuchFieldException, 
IllegalAccessException, MalformedURLException, NoSuchMethodException, 
InvocationTargetException {
  Field f = window.getClass().getDeclaredField("inputElements");
  f.setAccessible(true);
  LinkedHashMap<JLabel, JTextField> inputs = (LinkedHashMap<JLabel, 
  JTextField>) f.get(window);
  Field f2 = window.getClass().getDeclaredField("save");
  f2.setAccessible(true);
  JButton saveButton = (JButton) f2.get(window);
  inputs.get(window.getInputLabels().get(0)).setText("Testsender");
  inputs.get((window.getInputLabels().get(1))).setText("asdasdsa");
  ActionListener listener = saveButton.getActionListeners()[0];
  Method m = listener.getClass().getDeclaredMethod("saveStation");
  m.setAccessible(true);
  m.invoke(listener);
  expectedException.expect(MalformedURLException.class);
}


@After
public void tearDown() {
stationsToDelete.forEach(s -> 
H2DatabaseConnector.getInstance().deleteStation(s));
}

这是ActionListener中经过测试的方法:

private boolean saveStation() {
List<JLabel> keys = new ArrayList<>();
for (Map.Entry<JLabel, JTextField> inputElement : inputElements.entrySet()) {
    keys.add(inputElement.getKey());
}
String stationName = inputElements.get(keys.get(0)).getText();
String urlString = inputElements.get(keys.get(1)).getText();
URL stationURL = null;
try {
    stationURL = new URL(urlString);
} catch (MalformedURLException e) {
    JOptionPane.showMessageDialog(window, "Invalid URL!", "URL 
    not valid", JOptionPane.ERROR_MESSAGE);
    e.printStackTrace();
    return false;
}
Station s = new Station(stationName, stationURL);
if (checkStation(s)) {
    return WebradioPlayer.addStation(s);
}
return false;
}

如果我运行测试,我可以看到堆栈的tarce显示格式错误的url异常,消息为no协议:“ asdasdsa”,但测试失败。 有人可以解释我为什么吗? JUnit版本是4。

2 个答案:

答案 0 :(得分:2)

在调用确实引发异常的代码之前,必须先设置预期的异常

代替

@Test
public void saveStation() throws ... {
    // code here
    expectedException.expect(MalformedURLException.class);
}

您应该将测试方法写为

@Test
public void saveStation() throws ... {
    expectedException.expect(MalformedURLException.class);
    // code here
}

此外,如果您确实想抛出异常,则必须更改方法saveStation以不抑制异常。有关更多详细信息,请参见@Leviand的答案。

答案 1 :(得分:1)

您的测试失败了,因为您期望抛出一个异常(您说无效的url异常),但是您将该异常包装在try catch中,然后打印了堆栈跟踪。

try {
    stationURL = new URL(urlString);
} catch (MalformedURLException e) {
    JOptionPane.showMessageDialog(window, "Invalid URL!", "URL 
    not valid", JOptionPane.ERROR_MESSAGE);
    e.printStackTrace();
    return false;
}

您必须在捕获中添加trown声明,或者根本不捕获它,即:

} catch (MalformedURLException e) {
    JOptionPane.showMessageDialog(window, "Invalid URL!", "URL 
    not valid", JOptionPane.ERROR_MESSAGE);
    e.printStackTrace();
    throw new MalformedURLException(e);
}

并将抛出信息添加到您的方法中

private boolean saveStation() throws MalformedURLException{