it-swarm.com.de

Wie führe ich JUnit SpringJUnit4ClassRunner mit parametrisiert aus?

Der folgende Code ist aufgrund einer doppelten Annotation @RunWith ungültig:

@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(Parameterized.class)
@SpringApplicationConfiguration(classes = {ApplicationConfigTest.class})
public class ServiceTest {
}

Aber wie kann ich diese beiden Anmerkungen zusammen verwenden?

57
membersound

Dafür gibt es mindestens zwei Möglichkeiten:

  1. Folgende http://www.blog.project13.pl/index.php/coding/1077/runwith-junit4-with-both-springjunit4classrunner-und-parameterized/

    Ihr Test muss ungefähr so ​​aussehen:

     @RunWith(Parameterized.class)
     @ContextConfiguration(classes = {ApplicationConfigTest.class})
     public class ServiceTest {
    
         private TestContextManager testContextManager;
    
         @Before
         public void setUpContext() throws Exception {
             //this is where the magic happens, we actually do "by hand" what the spring runner would do for us,
            // read the JavaDoc for the class bellow to know exactly what it does, the method names are quite accurate though
           this.testContextManager = new TestContextManager(getClass());
           this.testContextManager.prepareTestInstance(this);
         }
         ...
     }
    
  2. Es gibt ein github-Projekt https://github.com/mmichaelis/spring-aware-rule , das auf dem vorherigen Blog aufbaut, aber auf allgemeine Weise Unterstützung hinzufügt

    @SuppressWarnings("InstanceMethodNamingConvention")
    @ContextConfiguration(classes = {ServiceTest.class})
    public class SpringAwareTest {
    
        @ClassRule
        public static final SpringAware SPRING_AWARE = SpringAware.forClass(SpringAwareTest.class);
    
        @Rule
        public TestRule springAwareMethod = SPRING_AWARE.forInstance(this);
    
        @Rule
        public TestName testName = new TestName();
    
        ...
    }
    

So können Sie eine Basisklasse einsetzen, die einen der Ansätze implementiert, und alle Tests, die davon erben.

34
mavarazy

Sie können SpringClassRule und SpringMethodRule verwenden - im Lieferumfang von Spring enthalten

import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.springframework.test.context.junit4.rules.SpringClassRule;
import org.springframework.test.context.junit4.rules.SpringMethodRule;

@RunWith(Parameterized.class)
@ContextConfiguration(...)
public class MyTest {

    @ClassRule
    public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();

    @Rule
    public final SpringMethodRule springMethodRule = new SpringMethodRule();

    ...
70
keyoxy

Es gibt eine andere Lösung mit JUnit 4.12 ohne Spring 4.2+.

In JUnit 4.12 wird ParametersRunnerFactory eingeführt, mit dem parametrisierte Tests und Federeinspritzungen kombiniert werden können.

public class SpringParametersRunnerFactory implements ParametersRunnerFactory {
@Override
  public Runner createRunnerForTestWithParameters(TestWithParameters test) throws InitializationError {
    final BlockJUnit4ClassRunnerWithParameters runnerWithParameters = new BlockJUnit4ClassRunnerWithParameters(test);
    return new SpringJUnit4ClassRunner(test.getTestClass().getJavaClass()) {
      @Override
      protected Object createTest() throws Exception {
        final Object testInstance = runnerWithParameters.createTest();
        getTestContextManager().prepareTestInstance(testInstance);
        return testInstance;
      }
    };
  }
}

Die Factory kann zur Testklasse hinzugefügt werden, um vollständige Unterstützung für Spring zu bieten, z. B. Testtransaktion , Dirty-Kontext wiederherstellen und Servlet-Test .

@UseParametersRunnerFactory(SpringParametersRunnerFactory.class)
@RunWith(Parameterized.class)
@ContextConfiguration(locations = {"/test-context.xml", "/mvc-context.xml"})
@WebAppConfiguration
@Transactional
@TransactionConfiguration
public class MyTransactionalTest {

  @Autowired
  private WebApplicationContext context;

  ...
}

Wenn Sie den Spring-Kontext innerhalb der statischen Methode @ Parameters benötigen, um Parameter für Testinstanzen bereitzustellen, lesen Sie bitte meine Antwort hier Wie kann ich den parametrisierten JUnit-Testläufer mit einem Feld verwenden, das mit Spring injiziert wurde? .

1
Arnor

Behandeln Sie den Anwendungskontext selbst

Was für mich funktionierte, war eine @RunWith(Parameterized.class) Test-Klasse, die den Anwendungskontext "von Hand" verwaltete.

Zu diesem Zweck habe ich einen Anwendungskontext mit derselben String-Sammlung erstellt, die in @ContextConfiguration enthalten wäre. Also statt zu haben

@ContextConfiguration(locations = { "classpath:spring-config-file1.xml",
    "classpath:spring-config-file2.xml" })

Ich hatte

ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[] {
            "classpath:spring-config-file1.xml", "classpath:spring-config-file2.xml"  });

Und für jedes @Autowired, das ich brauchte, holte ich es manuell aus dem erstellten Kontext:

SomeClass someBean = ctx.getBean("someClassAutowiredBean", SomeClass.class);

Vergessen Sie nicht, den Kontext am Ende zu schließen:

((ClassPathXmlApplicationContext) ctx).close();
0
manuelvigarcia