2016-12-07 85 views
1

我在寫一些叫做SqlCounter的特性(測試監聽器)。
它的目的 - 在測試執行過程中計算真正的SQL查詢。
如果此計數較大,則特殊env屬性 - 測試失敗。使用Spring和JUnit注入@Before和@Test之間的邏輯

問題是:我的@Before方法中有一些邏輯,它也運行了很多查詢。我需要的是在所有「之前」掛鉤之後(在測試方法執行開始之前)實際清除我的「SQL計數器」。

但所有已知的我的方式(org.springframework.test.context.support.AbstractTestExecutionListener:beforeTestMethod,org.junit.rules.TestWatcher:開始,org.junit.rules.TestRule:應用)執行之前JUnit的@Before :(
請幫助我;)

更新:
我想清除這個SQL計數器沒有明確(在每@​​Before),但在一些聽衆,必須正確@Before之間調用@測試註釋方法

+0

你能添加清除代碼在設置SQL執行後,@Before方法中的SQL計數器? –

+0

它在ttddyy/datasource-proxy(https://github.com/ttddyy/datasource-proxy)的幫助下實現,就像本文一樣 - https://vladmihalcea.com/2014/02/01/how-to-detect -n-plus-one-query-problem-testing-testing(QueryCountHolder.clear();) – Alex

回答

2

執行@Rule/@Before/@Test JUnit中的註釋序列取決於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

+0

這是一個奇蹟!真的很大 - 謝謝! ;) – Alex

相關問題