2012-03-15 71 views
2

我制作了一个MethodRule和@ Rule-annotation,可以让我的测试生活变得更轻松。 它检查是否抛出了特定的异常,并检查异常消息是否等于或包含给定的消息。JUnit MethodRule只测试一行

现在,当我运行testmethod多行测试时,它只需要第一行,并准备好了。我如何制作测试方法中的所有线?

这是我的代码: 注释:

@Retention(RetentionPolicy.RUNTIME) 
@Target({ElementType.METHOD}) 
public @interface ExpectedDomeinValidatieMessage { 
    String value() default ""; 
    String contains() default ""; 
} 

MethodRule:

@Override 
public Statement apply(final Statement base, final FrameworkMethod method, final Object target) { 
return new Statement() { 

    @Override 
    public void evaluate() throws Throwable { 
    ExpectedDomeinValidatieMessage message = method.getAnnotation(ExpectedDomeinValidatieMessage.class); 
    if (message == null) { 
     base.evaluate(); 
    } else { 
     try { 
     base.evaluate(); 
     Assert.fail("DomeinValidatieException not thrown"); 
     } catch (DomeinValidatieException e) { 
     if (StringUtils.isNotBlank(message.value())) { 
      if (!e.getMessage().equals(message.value())) { 
      throwException(e, "", message.value(), e.getMessage()); 
      } 
     } 
     if (StringUtils.isNotBlank(message.contains())) { 
      if (!e.getMessage().contains(message.contains())) { 
      throwException(e, "Segment niet gevonden:", message.contains(), e.getMessage()); 
      } 
     } 
     } 
    } 
    } 

    private void throwException(Throwable exception, String message, String expected, String actual) { 
    ComparisonFailure cf = new ComparisonFailure(message, expected, actual); 
    cf.setStackTrace(exception.getStackTrace()); 
    throw cf; 
    } 
}; 

用法:

@Test 
@ExpectedDomeinValidatieMessage("[Werkzaamheden] WerkzaamMetGevaarlijkeStoffen niet gevuld") 
public void valideerWerkzaamMetGevaarlijkeStoffen() throws DomeinValidatieException { 
    aanvraag.getVerzekerde().getWerkzaamheden().setWerkzaamMetGevaarlijkeStoffen(null); 
    validator.valideer(); 
} 

如果我这样使用它,它只是测试首测在方法中:

@Test 
@ExpectedDomeinValidatieMessage("[Werkzaamheden] WerkzaamMetGevaarlijkeStoffen niet gevuld") 
public void valideerWerkzaamMetGevaarlijkeStoffen() throws DomeinValidatieException { 
    aanvraag.getVerzekerde().getWerkzaamheden().setWerkzaamMetGevaarlijkeStoffen(null); 
    validator.valideer(); //Only this one is tested 
    aanvraag.getVerzekerde().getWerkzaamheden().setWerkzaamMetGevaarlijkeStoffen("bla"); 
    validator.valideer(); //This is NOT tested 
} 

回答

0

JUnit assertXXX方法通过抛出异常(特别是AssertionError)来工作。所以当抛出一个异常(通过你的代码或者断言)时,控制会退出测试方法。没有任何方法可以从抛出异常的位置重新启动。

您可能想要Parameterized,它允许您使用不同的参数多次运行相同的测试。

编辑:我怀疑valideer()抛出一个异常。为了进一步解释,让我们来解释一下你的代码。当你定义的规则,你要切实做好如下:

try { 
    base.evaluate(); // this calls valideerWerkzaamMetGevaarlijkeStoffen() 
    Assert.fail("DomeinValidatieException not thrown"); 
} catch (DomeinValidatieException e) { 
    // evaluate whether or not the test has failed or not 
} 

这意味着,如果你第一次调用valideer()抛出一个异常,则控制上面转移到catch块。没有机会继续执行测试,因为控制已经通过别处。您可以尽可能多地通过/不通过测试,但控制已传递到上面的catch块。

顺便说一句,MethodRule已被弃用在更高版本中,您应该使用TestRule来代替。

+0

马修,你描述失败的情况。当然,它会停止,那是预料之中的。但是当第一条测试线是好的时候,第二条线没有经过测试。 – 2012-03-15 08:28:50

+0

编辑答案包括更好的解释发生了什么事。 – 2012-03-15 09:20:43

+0

我想我明白了。当然它会抛出异常并通过控制。所以我已经超越了没有回报的地步,因为这不会被记录为错误。我会看看TestRule。 – 2012-03-15 10:27:07

0

通过调试器运行代码。我的猜测是,第一次打电话给valideer()确实会抛出异常,即使你不期望它。

+0

亚伦我认为你是对的。正如预期的那样,它抛出了DomeinValidatieException。所以可能这就是为什么只采取第一个可测试的LoC。现在我必须找到一种方法来抑制增加的错误... – 2012-03-15 09:12:57

+0

将它分成两个测试 – 2012-03-15 10:09:52