【问题标题】:JUnit expected exception not working as expectedJUnit 预期异常未按预期工作
【发布时间】:2018-07-20 06:58:27
【问题描述】:

我正在尝试测试 ActionListener 中的私有方法。如果传递了无效的 url,该方法应该抛出异常: 这是我的测试代码:

@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 异常,消息没有协议:'asdasdsa',但测试失败。 有人可以解释一下为什么吗? JUnit 版本为 4。

【问题讨论】:

    标签: java junit


    【解决方案1】:

    您必须在调用实际引发异常的代码之前设置预期的异常

    而不是

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

    你应该把测试方法写成

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

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

    【讨论】:

      【解决方案2】:

      您的测试失败,因为您期望抛出异常(您说无效的 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;
      }
      

      你必须在你的 catch 中添加 trown 声明,或者根本不捕捉它,即:

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

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

      private boolean saveStation() throws MalformedURLException{
      

      【讨论】:

      • 我想检查异常是否被抛出和捕获,但我不想让她通过方法签名中的参数获得“外部”。有机会工作吗?
      • 如果你想在 junit 测试中检查它,获得它的唯一方法是这样:如果从未到达他,他就不会意识到异常:)
      • 但是使用 mockito 我可以确保调用了 catch 块,对吧?
      • 使用 mockito 可以测试 catch 块的效果。验证 catch 块所做的更改确实发生了。
      猜你喜欢
      • 2022-01-23
      • 2020-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-12
      • 2018-05-29
      • 2019-04-19
      • 1970-01-01
      相关资源
      最近更新 更多