Есть ли какие-либо рекомендации, чтобы Junit выполнял функцию один раз в тестовом файле, и она также не должна быть статической.
как @BeforeClass
на нестатической функции?
Вот уродливое решение:
@Before void init(){
if (init.get() == false){
init.set(true);
// do once block
}
}
ну, это то, чего я не хочу делать, и я ищу интегрированное решение junit.
Ответы:
Если вы не хотите настраивать статические инициализаторы для одноразовой инициализации и не особо заинтересованы в использовании JUnit, взгляните на TestNG. TestNG поддерживает нестатическую одноразовую инициализацию с различными вариантами конфигурации, все с использованием аннотаций.
В TestNG это было бы эквивалентно:
@org.testng.annotations.BeforeClass public void setUpOnce() { // One time initialization. }
Для разборки,
@org.testng.annotations.AfterClass public void tearDownOnce() { // One time tear down. }
Для эквивалента TestNG JUnit 4
@Before
и@After
вы можете использовать@BeforeMethod
и@AfterMethod
соответственно.источник
Кажется, неплохо работает и простой оператор if:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = {"classpath:test-context.xml"}) public class myTest { public static boolean dbInit = false; @Autowired DbUtils dbUtils; @Before public void setUp(){ if(!dbInit){ dbUtils.dropTables(); dbUtils.createTables(); dbInit = true; } } ...
источник
@AfterClass
эквивалент, который разрушается после выполнения всех тестов?Самый простой выход - использовать пустой конструктор. Вы все еще можете переопределить конструктор в расширенном классе.
Но со всем наследством это не оптимально. Вот почему JUnit 4 вместо этого использует аннотации.
Другой вариант - создать вспомогательный метод в классе factory / util и позволить этому методу выполнять всю работу.
Если вы используете Spring, вам следует рассмотреть возможность использования
@TestExecutionListeners
аннотации. Что-то вроде этого теста:@RunWith(SpringJUnit4ClassRunner.class) @TestExecutionListeners({CustomTestExecutionListener.class, DependencyInjectionTestExecutionListener.class}) @ContextConfiguration("test-config.xml") public class DemoTest {
Spring
AbstractTestExecutionListener
содержит, например, этот пустой метод, который вы можете переопределить:public void beforeTestClass(TestContext testContext) throws Exception { /* no-op */ }
ПРИМЕЧАНИЕ: НЕ упускайте из виду / пропускайте
DependencyInjectionTestExecutionListener
при добавлении customTestExecutionListeners
. Если сделаешь, то все автопроводы будутnull
.источник
beforeTestClass()
вызвано до или после инициализации контекста?Легко используйте
@BeforeAllMethods
/@AfterAllMethods
аннотации для запуска метода внутри контекста экземпляра (нестатического), где будут доступны все введенные значения.Для этого есть специальная библиотека тестирования:
https://mvnrepository.com/artifact/org.bitbucket.radistao.test/before-after-spring-test-runner/0.1.0
https://bitbucket.org/radistao/before-after-spring-test-runner/
Единственное ограничение: работает только для тестирования Spring .
(Я разработчик этой библиотеки тестирования)
источник
Я никогда не пробовал, но, может быть, вы можете создать конструктор без аргументов и вызывать свою функцию оттуда?
источник
В статье обсуждаются 2 очень хороших решения этой проблемы:
источник
ОБНОВЛЕНИЕ: пожалуйста, посмотрите комментарий Черри, почему приведенное ниже предложение ошибочно. (Я сохраняю ответ здесь, а не удаляю, поскольку комментарий может предоставить полезную информацию другим о том, почему это не работает.)
Другой вариант, который стоит рассмотреть при использовании внедрения зависимостей (например, Spring)@PostConstruct
. Это гарантирует, что внедрение зависимости завершено, чего не было бы в конструкторе:@PostConstruct public void init() { // One-time initialization... }
источник
@Before
и@After
методы будут вызываться 6 раз! Так что в этом контексте@PostConstruct
ведет себя как@Before
аннотация. Вы можете просто протестировать это: просто поместите 2 тестовых метода в тестовый класс, добавьте@PostConstruct public void init() {System.out.println("started");}
и посмотрите в журналах, сколько раз он печатается.@Test
запуска: «Чтобы запустить метод, JUnit сначала создает новый экземпляр класса, а затем вызывает аннотированный метод».Просто используйте
@BeforeClass
:@BeforeClass public static void init() { }
Не имеет смысла
init
быть нестатическим, потому что каждый тест выполняется в отдельном экземпляре. Экземпляр, на которомinit
запущен, не будет соответствовать экземпляру какого-либо теста.Единственная причина, по которой вы можете захотеть, чтобы он был нестатическим, - это переопределить его в подклассах, но вы также можете сделать это с помощью статических методов. Просто используйте то же имя, и
init
будет вызван только метод подкласса .источник