java - 使用 Spring 和 JUnit 在 @Before 和 @Test 执行之间注入(inject)逻辑

标签 java spring spring-mvc junit

我正在编写一些名为 SqlCounter 的功能(测试监听器)。
它的目的是在测试执行期间对真实 SQL 查询进行计数。
如果此计数较大,则特殊环境属性 — 测试失败。

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

但是我知道的所有方法(org.springframework.test.context.support.AbstractTestExecutionListener:beforeTestMethod、org.junit.rules.TestWatcher:starting、org.junit.rules.TestRule:apply)都在 JUnit 的 @Before 之前执行: (
请帮助我;)

更新:
我想不是显式地清除这个 SQL 计数器(在每个 @Before 中),而是在某个监听器中,它必须在 @Before 和 @Test 带注释的方法之间调用

最佳答案

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

关于java - 使用 Spring 和 JUnit 在 @Before 和 @Test 执行之间注入(inject)逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41019687/

相关文章:

spring - 逃离| SpEL 中的(管道)

java - 相当于 Spring MVC 中请求的 @JsonIgnore

java - Mockito自调用doAnswer重复调用?

java - java中同步时方法的可访问性

Spring roo Vs( Wicket 口和 Spring )

java - Spring Java - 运行进程每天执行一次任务

java - 绕过 PUT 请求的唯一性 validator

Java - 想要将整数值类型转换为字节,这样我就可以以二进制格式写入文件

java - 二叉搜索树按字母搜索字符串

java - Spring MVC : Saving a Java List in PostgreSQL with Hibernate