使用Spring和JUnit

时间:2016-12-07 14:14:41

标签: java spring spring-mvc junit

我正在写一些名为SqlCounter的功能(测试监听器) 它的目的 - 在测试执行期间计算Real SQL查询 如果此计数更大,那么特殊的env属性 - 测试失败。

问题是:我的@Before方法中有一些逻辑,它也运行了很多查询。我需要的是清除我的" SQL计数器"实际上在所有"之前"钩子(在测试方法执行开始之前)。

但是我所知道的方式(org.springframework.test.context.support.AbstractTestExecutionListener:beforeTestMethod,org.junit.rules.TestWatcher:starting,org.junit.rules.TestRule:apply)在JUnit'之前执行。 s @Before :(
请帮帮我;)

更新:
我想明确地清除这个SQL计数器(在每个@Before中)但是在一些监听器中,必须在@Before和@Test注释方法之间调用

1 个答案:

答案 0 :(得分:2)

在JUnit中执行@Rule / @Before / @Test注释序列取决于Runner实现。我们可以说SpringJUnit4ClassRunner.methodBlockBlockJUnit4ClassRunner.methodBlock看起来像:

Statement statement = methodInvoker(frameworkMethod, testInstance);
statement = possiblyExpectingExceptions(frameworkMethod, testInstance, statement);
statement = withBefores(frameworkMethod, testInstance, statement);
...
statement = withRules...

基于此,我可以通过覆盖methodInvoker并添加新的@RightBeforeTest注释来提出以下实现

package info.test;

import org.junit.Before;
import org.junit.Test;
import org.junit.internal.runners.statements.RunBefores;
import org.junit.runner.RunWith;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import static org.junit.Assert.assertEquals;

@RunWith(JUnit4AnnotationsSequenceTest.CustomSpringJUnit4ClassRunner.class)
public class JUnit4AnnotationsSequenceTest
{
  private String value = null;

  @Before
  public void setUp()
  {
    value = "@Before.setUp";
  }

  @RightBeforeTest
  public void latestChance()
  {
    value = "@RightBeforeTest.latestChance"; 
  }

  @Test
  public void rightBeforeTestAnnotationExecutesAfterBeforeAnnotation()
  {
    assertEquals("@RightBeforeTest.latestChance", value);
  }

  public static class CustomSpringJUnit4ClassRunner extends SpringJUnit4ClassRunner
  {
    public CustomSpringJUnit4ClassRunner(final Class<?> clazz) throws InitializationError
    {
      super(clazz);
    }

    protected Statement methodInvoker(final FrameworkMethod method, final Object test)
    {
      return new RunBefores(
          super.methodInvoker(method, test),
          getTestClass().getAnnotatedMethods(RightBeforeTest.class),
          test);
    }
  }

  @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD)
  public @interface RightBeforeTest {}
}

test result