Порядок слушателей TestExecution

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfig.class, loader = AnnotationConfigContextLoader.class)
@TestExecutionListeners(listeners = LoadBalancingIntegrationTest.class, mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS)
public class LoadBalancingIntegrationTest extends AbstractTestExecutionListener{

    //...

    DummyWebAppService[] dummyWebAppControllers = new DummyWebAppService[4];

    int haproxyListeningPort = 8000;

    //DummyWebApp
    @Value("${dummyWebApp.mvnPath}")
    String mavenPath;

    @Value("${dummyWebApp.webAppPath}")
    String webAppPath;

    @Override
    public void beforeTestClass(TestContext testContext) throws Exception {
        dummyWebAppControllers[0] = new DummyWebAppService(mavenPath, webAppPath, 8080);
    }

    //..test cases follow
}

Я использую инъекцию весенней зависимости в своем тестовом примере. У меня проблема с порядком выполнения TestExecutionListeners. Согласно этой документации об упорядочении пользовательских TestExecutionListeners, порядок можно указать через интерфейс Ordered или аннотацию @Order и по умолчанию порядок имеет самый низкий приоритет для любого пользовательского TestExecutionListener. Однако при выполнении этого тестового класса перед любой инъекцией выполняется beforeTestClass. Я даже поставил mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS, чтобы не пропустить TestExecutionListeners по умолчанию. При комментировании beforeTestClass инъекция выполняется как обычно.

Мой вопрос: почему мой beforeTestClass выполняется первым? Могу ли я сказать, чтобы он выполнялся после инъекции?


person Thomas Oo    schedule 23.06.2017    source источник
comment
Подождите, этот класс должен быть тестом или прослушивателем исполнения? Вы смешиваете опасения.   -  person chrylis -cautiouslyoptimistic-    schedule 23.06.2017
comment
@chrylis Я просто использую TestExecutionListener для настройки метода beforeTestClass, поэтому оба, я не понимаю, почему я должен реорганизовать его прямо сейчас, я сделаю это после   -  person Thomas Oo    schedule 23.06.2017
comment
Может быть, чтобы уточнить, моя проблема не в том, что методы или внедрение зависимостей не работают, они есть, но в неправильном порядке. Сначала должно произойти внедрение зависимостей, а затем метод beforeTestClass.   -  person Thomas Oo    schedule 23.06.2017
comment
Это не сработает, потому что ваш тест — это testexecutionlistener. Проблема в смешении интересов.   -  person M. Deinum    schedule 23.06.2017


Ответы (1)


Не уверен, что это правильное исправление, но этого достаточно для моего варианта использования, который вводит bean-компоненты перед beforeTestClass. Просто заставьте его автоматически подключаться, написав @Override public void beforeTestClass(TestContext testContext) throws Exception { testContext.getApplicationContext().getAutowireCapableBeanFactory().autowireBean(this); dummyWebAppControllers[0] = new DummyWebAppService(mavenPath, webAppPath, 8080); }

Кажется немного хакерским, чтобы заставить autowire, но эй, моя проблема решена

person Thomas Oo    schedule 23.06.2017
comment
То, что вы делаете, уже хакерское имхо. У вас есть TestExecutionListener, который также является тестом. Это не то, что вы должны делать. Чтобы получить свойства, вы должны использовать Environment, а не @Value. Кроме того, то, что вы делаете здесь, вряд ли относится к TestExecutionListener и может быть легко достигнуто с помощью простого метода настройки, аннотированного @Before. - person M. Deinum; 23.06.2017
comment
@М. Deinum Мне не были ясны мои намерения по настройке этого тестового класса. Это интеграционный тест, в котором я запускаю различные фиктивные веб-приложения, запуск которых занимает много времени, поэтому я не использую @Before. Я хотел использовать @BeforeClass, но JUnit, конечно, настаивает на том, чтобы они были статическими. Теперь я столкнулся с проблемой, когда Spring не позволяет мне вводить статические объекты. Отсюда и этот beforeTestClass метод. Также я не понимаю необходимости использовать Environment? В этом сообщении говорится об обратном - person Thomas Oo; 23.06.2017
comment
Таким образом, вам не нужен @Value, вы можете просто использовать testContext.getApplicationContext().getEnvironment().getProperty(), чтобы удалить свой хак... Но, как уже говорилось, настоящая проблема заключается в том, что вы смешиваете проблемы здесь. - person M. Deinum; 23.06.2017
comment
Интересно, почему вы просто не создаете @Configuration и не создаете там эти bean-компоненты/экземпляры? Если они вам нужны в вашем тесте, это будет правильным способом без взлома файла TestExecutionListener. - person M. Deinum; 23.06.2017
comment
Вы правы, я должен просто использовать @Config .. все еще изучаю Spring здесь. Спасибо за помощь! - person Thomas Oo; 23.06.2017
comment
@M.Deinum @Value, вероятно, подходит для бегуна Spring, это просто все остальные организационные моменты. - person chrylis -cautiouslyoptimistic-; 24.06.2017
comment
Не для TestExecutionLIstener, который не будет автоматически подключен. - person M. Deinum; 25.06.2017