10 Stimmen

Transaktionaler parametrisierter Test von Spring und Autowiring

Gibt es eine Möglichkeit, eine Klasse, die AbstractTransactionalJUnit4SpringContexts erweitert, um schön mit JUnit eigenen @RunWith(Parameterized.class) zu spielen, so dass Felder als Autowired markiert richtig verdrahtet bekommen?

@RunWith(Parameterized.class)
public class Foo extends AbstractTransactionalJUnit4SpringContextTests {

    @Autowired private Bar bar

    @Parameters public static Collection<Object[]> data() {
        // return parameters, following pattern in
        // http://junit.org/apidocs/org/junit/runners/Parameterized.html
    }

    @Test public void someTest(){
        bar.baz() //NullPointerException
    }
}

6voto

Michal Moravcik Punkte 76

4voto

Simon LG Punkte 2837

Sie können einen TestContextManager von Spring verwenden. In diesem Beispiel verwende ich Theories anstelle von Parameterized.

@RunWith(Theories.class)
@ContextConfiguration(locations = "classpath:/spring-context.xml")
public class SeleniumCase {
  @DataPoints
  public static WebDriver[] drivers() {
    return new WebDriver[] { firefoxDriver, internetExplorerDriver };
  }

  private TestContextManager testContextManager;

  @Autowired
  SomethingDao dao;

  private static FirefoxDriver firefoxDriver = new FirefoxDriver();
  private static InternetExplorerDriver internetExplorerDriver = new InternetExplorerDriver();

  @AfterClass
  public static void tearDown() {
    firefoxDriver.close();
    internetExplorerDriver.close();
  }

  @Before
  public void setUpStringContext() throws Exception {
    testContextManager = new TestContextManager(getClass());
    testContextManager.prepareTestInstance(this);
  }

  @Theory
  public void testWork(WebDriver driver) {
    assertNotNull(driver);
    assertNotNull(dao);
  }
}

Ich habe diese Lösung hier gefunden: Wie man parametrisierte/theoretische Tests mit Spring durchführt

2voto

yanefedor Punkte 1742

Sie können verwenden SpringClassRule y SpringMethodRule zu diesem Zweck

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

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

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

    @Autowired 
    private Bar bar

    @Parameters 
    public static Collection<Object[]> data() {
        // return parameters, following pattern in
        // http://junit.org/apidocs/org/junit/runners/Parameterized.html
    }

    @Test 
    public void someTest() {
        bar.baz() //NullPointerException
    }
}

1voto

Bozho Punkte 570413

Nein, das können Sie nicht. Die Oberklasse hat:

@RunWith(SpringJUnit4ClassRunner.class)

die sicherstellt, dass die Tests im Spring-Kontext ausgeführt werden. Wenn Sie sie ersetzen, verlieren Sie dies.

Was mir als Alternative einfällt, ist die Ausweitung SpringJunit4ClassRunner zur Verfügung, stellen Sie dort Ihre benutzerdefinierte Funktionalität bereit und verwenden Sie sie mit @RunWith(..) . So haben Sie den Spring-Kontext und Ihre zusätzliche Funktionalität. Er ruft super.createTest(..) und führen Sie dann zusätzliche Aufgaben für den Test durch.

0voto

prule Punkte 2478

Ich musste die Transaktionen programmatisch abwickeln (siehe http://www.javathinking.com/2011/09/junit-parameterized-test-with-spring-autowiring-and-transactions/ ):

@RunWith(Parameterized.class)
@ContextConfiguration(locations = "classpath*:/testContext.xml")
public class MyTest {

    @Autowired
    PlatformTransactionManager transactionManager;

    private TestContextManager testContextManager;

    public MyTest (... parameters for test) {
        // store parameters in instance variables
    }

    @Before
    public void setUpSpringContext() throws Exception {
        testContextManager = new TestContextManager(getClass());
        testContextManager.prepareTestInstance(this);
    }

    @Parameterized.Parameters
    public static Collection<Object[]> generateData() throws Exception {
        ArrayList list = new ArrayList();
        // add data for each test here
        return list;
    }

    @Test
    public void validDataShouldLoadFully() throws Exception {
        new TransactionTemplate(transactionManager).execute(new TransactionCallback() {
            public Object doInTransaction(TransactionStatus status) {
                status.setRollbackOnly();
                try {
                    ... do cool stuff here

                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
                return null;
            }
        });

    }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X