带有expected = exception的Java测试失败,出现断言错误

时间:2016-08-10 16:06:40

标签: java exception junit

我遇到了测试用例的问题。

正在测试的方法有一个try / catch,它捕获MalformedURLException,但在测试过程中,由于遇到MalformedURLException的Junit AssertionError而导致失败。但我无法找出实际投掷的内容!这是我的代码(在eclipse中创建为MWE)。

我想测试的方法

public void throwMalFormedURLException(){

    String s = new String("www.google.com");

    try{
        url = new URL(s);
    }catch (Exception e){
        e.printStackTrace();
        e.getClass();
        e.getCause();
    }


}

测试方法

@Test (expected = MalformedURLException.class)
public void testThrowMalFormedURLException() {
    MWE testClass = new MWE();
    testClass.throwMalFormedURLException();
    System.out.println("End of test");
}

这是控制台中的输出

  

测试结束时的错误详细信息如下:java.net.MalformedURLException:无协议:www.google.com
    在java.net.URL。(URL.java:593)
    在java.net.URL。(URL.java:490)
    在java.net.URL。(URL.java:439)
    在MWE.throwMalFormedURLException(MWE.java:12)
    在testMWE.testThrowMalFormedURLException(testMWE.java:12)

在Junit控制台中,它说:

  

java.lang.AssertionError:预期的异常:Java.net.MalformedURLException

但Junit报告失败,即使控制台告诉我我有一个MalformedURLException。

这次测试我做错了什么?

感谢您的想法。

大卫

3 个答案:

答案 0 :(得分:6)

您正在捕获异常,因此不会被抛出。

如果您的目的是测试您是否正在捕获异常并将其正确地转发回“用户”,那么您应该专门为此创建测试。您可能不希望单元测试中的UI元素*因此这是一个抽象和DI有很多价值的地方。一种简单的方法是创建一个模拟对象,该对象将侦听错误消息并在收到消息时标记标记。单元测试会触发错误,然后在标志设置后通过。您还应该进行否定测试或断言在抛出异常之前未设置该标志。

*测试UI也是一个好主意,但它可能有点慢。有各种自动化工具。它通常属于不同的测试阶段。你真的希望单元测试非常快,以便你可以非常频繁地运行它们。

答案 1 :(得分:2)

您编写的生产代码根本无法测试。更具体地说:这个代码首先没有任何“编程”可观察的副作用。

含义:当你编写“生产代码”时,方法中的代码可以做三件事情:

  1. 对作为测试类的字段的对象进行方法调用
  2. 返回一些值
  3. 抛出异常
  4. 对于这些选项中的每一个,您都可以编写测试代码:

    1. 使用依赖注入,您可以将模拟对象放入正在测试的类中。然后你可以检查你的模拟对象上是否调用了预期的方法;使用您期望的参数。
    2. 您将调用该方法得到的结果与某些预期值进行比较
    3. 您使用expected确保抛出特定异常
    4. 当你查看你的代码;你可以看到:它没有那个。它仅对在方法中创建的对象进行操作。它不会返回任何值。而且,最重要的是:它不会引发异常!

      长话短说:一个被抓住的例外不是“离开”这个方法。它被捕获,并且该方法正常结束。您打印有关捕获的异常的详细信息这一事实不会改变它。

      所以,首先要做的是:从生产代码中删除整个try / catch!

      而且,如果您想进行更具体的测试,可以执行以下操作:

      @Test
      public void testException() {
        try { 
          new MWE().throwMalFormedURLException();
          fail("should have thrown!");
        } catch ( MalFormedURLException me ) {
          assertThat(me.getMessage(), containsString("whatever"));
        }
      

      以上:

      1. 在没有抛出异常时失败
      2. 在抛出除MalFormedURLException之外的任何其他异常时失败
      3. 允许您检查抛出异常的其他属性

答案 2 :(得分:0)

这是一个有效的测试失败。测试断言调用throwMalFormedURLException()将抛出MalformedURLException,但由于您正在捕获异常,因此它不会抛出异常,因此测试失败。