我正在写一些名为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注释方法之间调用
答案 0 :(得分:2)
在JUnit中执行@Rule
/ @Before
/ @Test
注释序列取决于Runner实现。我们可以说SpringJUnit4ClassRunner.methodBlock
或BlockJUnit4ClassRunner.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 {}
}