2016-12-07 7 views
1

J'écris une fonction (écouteur de test) appelée SqlCounter.
Son but est de compter les requêtes SQL réelles pendant l'exécution du test.
Si ce nombre est plus grand, la propriété env spéciale - test échoue.Injection de la logique entre @Before et l'exécution de @Test avec Spring et JUnit

Le problème est que: J'ai une certaine logique dans mes méthodes @Before, qui exécutent également beaucoup de requêtes. Ce dont j'ai besoin, c'est d'effacer mon "compteur SQL" après tous les hooks "avant" (juste avant le début de l'exécution de la méthode de test).

Mais tous connus de façons moi (org.springframework.test.context.support.AbstractTestExecutionListener: beforeTestMethod, org.junit.rules.TestWatcher: départ, org.junit.rules.TestRule: appliquer) exécuter AVANT @Before JUnit :(
Aidez-moi, s'il vous plaît;)

Mise à jour:
Je veux effacer ce compteur SQL pas explicitement (dans la @Before tous), mais dans l'un certain auditeur, qui doit être invoqué à droite entre @Before et @ Test des méthodes annotées

+0

pouvez-vous ajouter le code qui efface le compteur SQL dans votre méthode @Before APRÈS l'exécution SQL? –

+0

il est implémenté avec l'aide de ttddyy/datasource-proxy (https://github.com/ttddyy/datasource-proxy) comme dans cet article - https://vladmihalcea.com/2014/02/01/how-to-detect -le-n-plus-un-question-problème-pendant-testing (QueryCountHolder.clear();) – Alex

Répondre

2

Exécution de @Rule/@Before/@Test La séquence d'annotations dans JUnit dépend d'une implémentation Runner. Disons que SpringJUnit4ClassRunner.methodBlock ou BlockJUnit4ClassRunner.methodBlock ressemble:

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

Basé sur ce que je peux proposer la mise en œuvre suivante avec dépassement methodInvoker et l'ajout d'une nouvelle annotation @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

C'est un miracle! Vraiment Big-Big merci! ;) – Alex