2016-12-07 6 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前に実行
私はすべての@Beforeで(NOT明示的にこのSQLカウンタをクリアしたい )が、中に@Beforeとの間で右に呼び出されなければならないいくつかのリスナー、@:)

更新; :(
は、私を助けてください注釈付きメソッドのテスト

+0

を追加することで、以下の実施を提案することができることに基づいて

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

あなたはクリアコードを追加することができますあなたの@BeforeメソッドのSQLカウンタは、セットアップされた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-during-testing(QueryCountHolder.clear();) – Alex

答えて

2

@Rule/@Before/の実行JUnitの注釈シーケンスはRunnerの実装に依存します。さんは次のようにSpringJUnit4ClassRunner.methodBlockBlockJUnit4ClassRunner.methodBlock見えを言ってみましょう:私は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

関連する問題