Как вы управляете фиктивными данными, используемыми для тестов? Хранить их вместе с соответствующими сущностями? В отдельном тестовом проекте? Загрузить их с помощью сериализатора из внешних ресурсов? Или просто воссоздать их там, где это необходимо?
У нас есть стек приложений с несколькими модулями, зависящими от другого, каждый из которых содержит объекты. Каждый модуль имеет свои собственные тесты и нуждается в фиктивных данных для запуска.
Теперь модулю с большим количеством зависимостей потребуется много фиктивных данных из других модулей. Однако они не публикуют свои фиктивные объекты, потому что они являются частью тестовых ресурсов, поэтому все модули должны снова и снова настраивать все фиктивные объекты, которые им нужны.
Кроме того: большинство полей в наших сущностях не могут быть обнулены, поэтому даже выполнение транзакций на уровне объекта требует, чтобы они содержали какое-то значение, в большинстве случаев с дополнительными ограничениями, такими как уникальность, длина и т. д.
Есть ли лучший выход из этого или все решения компромиссы?
Подробнее
Наш стек выглядит примерно так:
Один модуль:
src/main/java --> gets jared (.../entities/*.java contains the entities)
src/main/resources --> gets jared
src/test/java --> contains dummy object setup, will NOT get jared
src/test/resources --> not jared
Мы используем Maven для обработки зависимостей.
пример модуля:
- Модуль A содержит несколько фиктивных объектов
- Модулю B нужны свои собственные объекты И такие же, как у модуля A
Вариант а)
Тестовый модуль T может содержать все фиктивные объекты и предоставлять их в тестовой области (так что загруженные зависимости не будут искажены) для всех тестов во всех модулях. Будет ли это работать? Значение: если я загружу T в A и запущу установку на A, он НЕ будет содержать ссылок, введенных T, особенно не B? Однако тогда A будет знать о модели данных B.
Вариант б)
Модуль A предоставляет фиктивные объекты где-то в src/main/java../entities/dummy
, позволяя B получить их, в то время как A не знает о фиктивных данных B.
Вариант в)
Каждый модуль содержит внешние ресурсы, которые представляют собой сериализованные фиктивные объекты. Они могут быть десериализованы тестовой средой, которая в них нуждается, поскольку она зависит от модуля, которому они принадлежат. Это потребует от каждого модуля создания и сериализации своих фиктивных объектов, и как это сделать? Если с другим модульным тестом он вводит зависимости между модульными тестами, которые никогда не должны происходить, или со сценарием, его будет сложно отлаживать и он не будет гибким.
Вариант г)
Используйте фиктивную структуру и назначайте необходимые поля вручную для каждого теста по мере необходимости. Проблема здесь в том, что большинство полей в наших сущностях не могут принимать значения NULL и, следовательно, потребуют вызова сеттеров или конструкторов, что приведет к тому, что мы снова окажемся в начале.
Чего мы не хотим
Мы не хотим создавать статическую базу данных со статическими данными, так как требуемая структура объектов будет постоянно меняться. Много сейчас, чуть позже. Итак, мы хотим, чтобы hibernate настраивал все таблицы и столбцы и заполнял их данными во время модульного тестирования. Кроме того, статическая база данных может привести к большому количеству потенциальных ошибок и тестовых взаимозависимостей.
Мои мысли идут в правильном направлении? Как лучше всего справляться с тестами, требующими большого количества данных? У нас будет несколько взаимозависимых модулей, которым потребуются объекты, заполненные какими-то данными из нескольких других модулей.
ИЗМЕНИТЬ
Еще немного информации о том, как мы это делаем прямо сейчас в ответ на второй ответ:
Итак, для простоты у нас есть три модуля: Person
, Product
, Order
. Person
проверит некоторые методы менеджера, используя объект MockPerson
:
(в person/src/test/java :)
public class MockPerson {
public Person mockPerson(parameters...) {
return mockedPerson;
}
}
public class TestPerson() {
@Inject
private MockPerson mockPerson;
public testCreate() {
Person person = mockPerson.mockPerson(...);
// Asserts...
}
}
Класс MockPerson
не будет упакован.
То же самое относится и к тестированию продукта:
(в product/src/test/java:)
public class MockProduct() { ... }
public class TestProduct {
@Inject
private MockProduct mockProduct;
// ...
}
MockProduct
необходим, но не будет упакован.
Теперь для тестов порядка потребуются MockPerson
и MockProduct
, так что теперь нам нужно создать оба, а также MockOrder
для проверки Order
.
(в порядок/источник/тест/java :)
Это дубликаты, и их нужно будет менять каждый раз при изменении Person
или Product
.
public class MockProduct() { ... }
public class MockPerson() { ... }
Это единственный класс, который должен быть здесь:
public class MockOrder() { ... }
public class TestOrder() {
@Inject
private order.MockPerson mockPerson;
@Inject
private order.MockProduct mockProduct;
@Inject
private order.MockOrder mockOrder;
public testCreate() {
Order order = mockOrder.mockOrder(mockPerson.mockPerson(), mockProduct.mockProduct());
// Asserts...
}
}
Проблема в том, что теперь мы должны обновлять person.MockPerson
и order.MockPerson
всякий раз, когда изменяется Person
.
Не лучше ли просто опубликовать Mocks с помощью jar, чтобы любой другой тест, который в любом случае имеет зависимость, мог просто вызвать Mock.mock и получить хорошо настроенный объект? Или это темная сторона - легкий путь?