В чем разница между @BeforeClass и Spring @TestExecutionListener beforeTestClass()

в чем разница между использованием JUnit @BeforeClass и Spring @TestExecutionListener beforeTestClass(TestContext testContext) "крюк"? Если есть разница, какой из них использовать, при каких обстоятельствах?

Зависимости Maven:
весна-сердечник:3.0.6.Отпустите
весна-контекст:3.0.6.Отпустите
весна-испытание:3.0.6.Отпустите
spring-data-commons-core: 1.2.0.М1
весна-данные-mongodb: 1.0.0.М4
mongo-java-драйвер: 2.7.3
junit: 4.9
cglib:2.2

использование аннотации JUnit @BeforeClass:

import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;

@ContextConfiguration(locations = { "classpath:test-config.xml" })
public class TestNothing extends AbstractJUnit4SpringContextTests {

    @Autowired
    PersonRepository repo;

    @BeforeClass
    public static void runBefore() {
        System.out.println("@BeforeClass: set up.");
    }

    @Test
    public void testInit() {
        Assert.assertTrue(repo.findAll().size() == 0 );
    }
}

=> @BeforeClass: set up.
=> Process finished with exit code 0

использование пружинного крючка:

(1) переопределить beforeTestClass(TextContext testContext):

import org.springframework.test.context.TestContext;
import org.springframework.test.context.support.AbstractTestExecutionListener;

public class BeforeClassHook extends AbstractTestExecutionListener {

    public BeforeClassHook() { }

    @Override
    public void beforeTestClass(TestContext testContext) {
        System.out.println("BeforeClassHook.beforeTestClass(): set up.");
    }
}

(2) Используйте @TestExecutionListeners аннотация:

import org.springframework.test.context.TestExecutionListeners;  
// other imports are the same    

@ContextConfiguration(locations = { "classpath:test-config.xml" })
@TestExecutionListeners(BeforeClassHook.class)
public class TestNothing extends AbstractJUnit4SpringContextTests {

    @Autowired
    PersonRepository repo;

    @Test
    public void testInit() {
        Assert.assertTrue(repo.findAll().size() == 0 );
    }
}

=> BeforeClassHook.beforeTestClass(): set up.
=> Process finished with exit code 0

2 ответов


TestExecutionListeners - Это способ экстернализации многоразового кода, который инструменты тесты.

как таковой, если вы реализуете TestExecutionListener вы можете повторно использовать его в иерархиях тестовых классов и, возможно, в проектах, в зависимости от ваших потребностей.

С другой стороны, a @BeforeClass метод, естественно, может использоваться только в пределах одной иерархии тестовых классов.

обратите внимание, однако, что JUnit также поддерживает правила: если вы реализуете org.junit.rules.TestRule вы можете объявить его как @ClassRule для достижения той же цели... с дополнительным преимуществом, что правило JUnit можно повторно использовать так же, как Spring TestExecutionListener.

так что это действительно зависит от вашего варианта использования. Если вам нужно использовать функцию "перед классом" только в одном тестовом классе или иерархии одного тестового класса, тогда вам лучше пойти по простому маршруту просто реализации @BeforeClass метод. Однако, если вы предвидите, что вам понадобится функциональность "перед классом" в разных иерархии тестовых классов или между проектами следует рассмотреть возможность реализации пользовательского TestExecutionListener или Правило JUnit.

преимущество весны TestExecutionListener над правилом JUnit это TestExecutionListener имеет доступ к TestContext и поэтому доступ к источнику ApplicationContext к которому правило JUnit не будет иметь доступа. Кроме того,TestExecutionListener может быть автоматически обнаружен и приказал.

обзоры Ресурсы:

С уважением,

Сэм (автор Spring Testcontext Framework)


первое решение с @BeforeClass не имеет загруженного контекста приложения. Я сделал расширенные AbstractJUnit4SpringContextTests и определил @ContextConfiguration. Я думаю, что listner-единственный способ получить контекст, загруженный до Метода @beforeclass. Или даже лучше расширить класс SpringJUnit4ClassRunner, как упоминалось здесь