2015-12-23 25 views
1

因此,我需要为我正在改进的一些(遗留)代码编写测试。在一个方法中,我尝试解析一些字符串(这应该是合法的JSON)。然后如果字符串不代表有效的JSON,则可能会捕获JSONException。例如:JUnit测试:如何使用try-catch块检查错误

public void transformToJSON(String source) { 
    try { 
    JSONObject js = new JSONObject(new JSONTokener(item.getHtml())); 
    } 
    catch (JSONException e) { 
    log(e) 
    } 
    //than js is added to an Hashset and the method is done 
} 

所以我想写一个良好的输入测试(看看我是否已经生成了正确的JSON对象)。通过检查Set中的对象,这很容易。

但是,对于错误的输入,我需要找出是否抛出了正确的错误。 我知道如果在代码中出现错误,我可以在测试中检查它。

  • 通过设置规则​​并在测试方法中检查它。
  • 通过测试

try..catch块都不会工作上面加了@Test(expected = JSONException.class)

如何测试捕获块是否捕获到适当的异常?我想尽可能少地改变源代码。

+0

这一切都取决于什么'日志(JSONException)'方法不会因为你想验证它在你预期的时候被调用。验证这个最好的方法是使用一个测试double并验证这个调用,例如使用Mockito,[但是您必须准备好注入记录器以允许在测试中替换真正的记录器](http:// stackoverflow.com/q/9841623/1240557)。 – kryger

回答

1

在JUnit测试类中,您可以在try或catch块中使用fail("this should not have happened"),具体取决于应该做什么和不应该做什么(例如:在JUnit类中尝试并捕获,而不是在实际的方法中!)。

但是,在您的方法中使用try/catch块时,无法查看是否发生了异常,因为它是在方法内处理的。所以,你将不得不扔在方法的异常,而不是捕捉它,即

public void transformToJSON(String source) throws JSONException { ... } 

然后它会工作,检查异常是否发生与否。

或者,您可以返回一个布尔值,指出转换是否成功。然后,您可以测试返回值是否为真/假,如果这是您的预期。

public boolean transformToJSON(String source) { 
    boolean success = true; 
    try { 
    JSONObject js = new JSONObject(new JSONTokener(item.getHtml())); 
    } 
    catch (JSONException e) { 
    log(e) 
    success = false; 
    } 
    //than js is added to an Hashset and the method is done 
    return success; 
} 

在您的测试类:

@Test 
public void testTransformToJSON() { 
     assertTrue(transformToJSON("whatever")); 
} 
+0

感谢您提供关于失败陈述的说明,未来它可能会很方便。然而,我并不想'抛出'异常,因为方法中抛出了多个JSONException,并且需要对它们进行处理(它们被广泛记录)。 –

+0

@SanderB我对如何测试是否发生异常做了编辑。 – LordAnomander

+0

不错的想法,但我不能只是将方法返回参数从void更改为布尔值(我可能已经简化了一下,它实际上是非常复杂的代码)。 但是,这是一个相当简单的测试,我没有想到它完成后它会改变。 (无论如何,这个方法需要被公开声明)所以我认为这个答案是我要去的(除非一些高级的JUnit测试方法出现) –

0

你的遗留代码正在吞噬异常。如果它抛出一个异常,那么你的junit @Test(expected = JSONException.class)就可以工作。

+0

我知道,关键是我不想扔一个例外。异常被广泛记录,并且抛出了多个JSONException(一个用于JSONArray,一个用于JSONObject),所以我需要立即捕获它们。谢谢你的回答! –

0

我想稍微改变代码,以便它是

public void transformToJSON(String source) { 
    try { 
    JSONObject js = getJSON(item.getHtml())); 
    } 
    catch (JSONException e) { 
    log(e) 
    } 
    //than js is added to an Hashset and the method is done 
} 

public JSONObject getJSON(String source) throws JSONException { 
    return new JSONObject(new JSONTokener(source)); 
} 

,然后针对的getJSON测试。这引发了一个异常,正如其他人所说的(和你),你可以在测试类中使用expectedException

1

根据代码中使用的日志记录,可以使用Mockito来验证在catch块内记录的消息。

请继续通过有关设置单元下面的链接查看更多细节测试

http://bloodredsun.com/2010/12/09/checking-logging-in-unit-tests/

+0

哇,非常好!这是我的情况最有用的,我不知道它存在! 但是,我会留下tbrown的解决方案,因为它是最普遍的(也许人们正在寻找一个不使用日志记录的答案)。但是非常感谢您的关注! –

+0

没关系。我很高兴这对你有帮助! – shivdim

0
use a bad formatted json string, and then do assertions or whatever in the catch block of ur test. 



      @Test 
      public void shouldCatchException(){ 
       String source = "{ \"name\":\"John\", \"age\":30, \"car\":null "; 
      try { 
        jsonHelper.transformToJSON(source); 
       }catch (JSONException e){ 
        Assert.assertThat(e, notNullValue()); 
        assertTrue(StringUtils.isNotBlank(e.getMessage()); 
        //whatever else u need to assert 
       } 
      }