JUnit MethodRule仅测试一行

时间:2012-03-15 07:57:00

标签: java junit

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

现在,当我运行一个测试方法,测试更多行时,它只需要第一行而不是准备就绪。我如何测试测试方法中的所有线条?

这是我的代码: 注释:

@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
}

2 个答案:

答案 0 :(得分: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。

答案 1 :(得分:0)

通过调试器运行代码。我的猜测是第一次调用valideer()确实会引发异常,即使你不期望它。