Как загрузить данные теста DBUnit один раз в каждом случае с помощью Spring Test
Spring Тест помогает сбрасывать любые изменения, внесенные в базу данных в рамках тестового метода. Это означает, что нет необходимости тратить время на удаление/перезагрузку тестовых данных перед каждым методом тестирования.
Но если вы используете аннотацию @BeforeClass Junit, то это вынуждает загрузчик данных быть статичным. Вопрос, который рассматривается здесь: Почему атрибут jUnit's fixtureSetup статичен?
Если метод инициализации данных статичен, то должны быть методы подключения данных и источник данных... и далее... заставлять все статично... что не будет работать. В какой момент я спрашиваю: какая польза от Spring Возможность проверки отката, когда вам нужно удалить/перезагрузить тестовые данные в любом случае для каждого теста?!?!
Ответы
Ответ 1
Один из подходов, который работает, - создать класс "инициализатор данных", добавить его в тестовый контекст приложения Spring, который также имеет ваш источник данных, и связать этот контекст приложения с вашими тестами. Это зависит от того, что Spring кэширует контекст приложения между тестовыми вызовами.
Например, тестовый суперкласс:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:test-application-context.xml"})
@Transactional
public abstract class DataLoadingTest {
@Autowired
protected DatabaseInitialiser databaseInitialiser;
}
С test-application-context.xml
:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="dataSource" .../>
<bean class="DatabaseInitialiser">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
и
public class DatabaseInitialiser extends JdbcDaoSupport {
@PostConstruct
public void load() {
// Initialise your database here: create schema, use DBUnit to load data, etc.
}
}
В этом примере:
- все тесты, основанные на базе данных, расширяются
DataLoadingTest
;
- Spring инициализирует контекст приложения при первом вызове вызова;
- это вызывает
DatabaseInitialiser.load()
через аннотацию @PostConstruct
;
- Spring поддерживает контекст приложения в кеше;
- дополнительно проверит провод вызовов в
DatabaseInitialiser
из контекста приложения, который уже кэшируется;
- тесты являются транзакционными и откат в конце до исходного набора данных.
Аналогично, DatabaseInitialiser
может иметь аннотированный метод @PostDestroy
для выполнения любого отката, необходимого в конце всего тестового прогона.
Ответ 2
Spring Test и DbUnit - две отличные рамки. Но совместить их не имеет смысла. Поскольку Spring Test выполняет откат по соединению, он очищается после этого, а DbUnit очищает и вставляет тестовые данные в метод @Before
.
Используйте Spring, если вы не зависите от каких-либо динамических данных и dbUnit в противном случае.
Ответ 3
Мы используем DBUnit совместно с Spring Test широко. Но мы не используем функцию DBUnit для удаления данных в конце теста.
Мы помещаем кучу вложений DBUnit для наших тестовых данных в методе @Before для инициализации теста. Затем, когда тест завершен, мы позволяем функции отката Spring вернуть базу данных в исходное состояние.
Самая большая проблема, с которой мы имеем дело, заключается в том, что данные DBUnit должны быть загружены перед каждым тестом, что может стать серьезным хитом производительности. Большинство наших тестов с использованием DBUnit читаются только, проверяя поведение приложения на основе определенного предопределенного поведения. Таким образом, у нас есть привычка создавать мастер-тесты, которые затем запускают все мелкие зерновые тесты в партии в рамках одной и той же транзакции.
Ответ 4
Способы аннотируются с помощью @BeforeTransaction, как следует из названия, до начала транзакции каждого теста. Если в таком методе вы можете определить, загружены ли тестовые данные, тогда при необходимости можно загрузить данные.
Помните, что данные остаются в вашей (в памяти) базе данных для всех последующих тестов.
Мы используем это для загрузки "статических" данных, которые в рабочей среде также будут загружены в нашу базу данных при ее запуске. Таким образом, мы фактически используем точно такой же код и данные для наших тестов, а не полагаемся на экспорт (DbUnit), который может устареть.