Как загрузить тестовые данные DBUnit один раз для каждого случая с помощью Spring Test - PullRequest
12 голосов
/ 09 июня 2010

Spring Test помогает откатить любые изменения, внесенные в базу данных в рамках метода тестирования.Это означает, что нет необходимости тратить время на удаление / перезагрузку тестовых данных перед каждым методом тестирования.

Но если вы используете аннотацию @BeforeClass Junit, то это заставляет загрузчик данных быть статическим.Вопрос, который рассматривается здесь: Почему jUnit fixtureSetup должен быть статическим?

Если метод инициализации данных является статическим, то и методы подключения к данным, и источник данных должны быть включены... заставляя все быть статичным ... что не будет работать.В какой момент я спрашиваю - что хорошего в способности Spring Test откатывать изменения, когда вам все равно приходится удалять / перезагружать тестовые данные для каждого теста ??!?!

Ответы [ 4 ]

14 голосов
/ 25 января 2012

Один из подходов, который работает, - это создать класс «инициализатора данных», добавить его в контекст приложения 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>

And

public class DatabaseInitialiser extends JdbcDaoSupport {
    @PostConstruct
    public void load() {
        // Initialise your database here: create schema, use DBUnit to load data, etc.
    }
}

В этом примере:

  • все тесты, основанные на базе данных, расширяются DataLoadingTest;
  • Spring инициализирует контекст приложения при первом тестированииinvocation;
  • это вызывает DatabaseInitialiser.load() через аннотацию @PostConstruct;
  • Spring сохраняет контекст приложения в кэше;
  • дальнейшие тестовые вызовы передаются в DatabaseInitialiser из контекста приложения, который уже кэширован;
  • тесты являются транзакционными и в конце возвращаются к исходному набору данных.

Аналогично, DatabaseInitialiser может иметьаннотированный метод @PostDestroy для выполнения любого отката, необходимого в конце всего тестового прогона.

1 голос
/ 28 июня 2011

Мы широко используем DBUnit в сочетании с Spring Test.Но мы не используем функциональность DBUnit для удаления данных в конце теста.

Мы поместили несколько вставок DBUnit для наших тестовых данных в метод @Before, чтобы инициализировать тест.Затем, когда тест завершен, мы позволяем функциональности пружинного отката вернуть базу данных в исходное состояние.

Самая большая проблема, с которой мы сталкиваемся, заключается в том, что данные DBUnit должны загружаться перед каждым тестом, что может бытьосновной удар по производительности.Большинство наших тестов, использующих DBUnit, доступны только для чтения, тестируя поведение приложения на основе определенного предопределенного поведения.Таким образом, у нас есть привычка создавать главные тесты, которые затем запускают все точные тесты зерна в пакете в пределах одной транзакции.

1 голос
/ 10 июня 2010

Spring Test и DbUnit - это две отличные фреймворки.Но не имеет смысла объединять их.Поскольку Spring Test выполняет откат для соединения, он впоследствии очищается, а DbUnit очищает и вставляет тестовые данные в метод @Before.

Используйте Spring, если вы не зависите от каких-либо динамических данных, и dbUnitиначе.

0 голосов
/ 31 января 2013

Методы с аннотацией @ BeforeTransaction запускаются, как следует из названия, перед началом транзакции каждого теста. Если в таком методе вы можете определить, загружены ли тестовые данные, тогда вы можете загрузить данные при необходимости.

Остерегайтесь того, что данные остаются в вашей (в памяти) базе данных для всех последующих тестов.

Мы используем это для загрузки «статических» данных, которые в производственной среде также будут загружаться в нашу базу данных при запуске. Таким образом, мы фактически используем точно такой же код и данные для наших тестов, вместо того, чтобы полагаться на (DbUnit) экспорт, который может устареть.

...