Spring test data generator
В статье будет обзор на недавно написанную мною либу для упрощения генерации тестовых данных.
Что позволяет делать библиотека:
-
Генерировать валидные тестовые данные.
-
Расширять стандартный набор резолверов для валидационных аннотаций (об этом ниже).
-
Предоставляет способ объяснить как конструировать ваш объект, если ваш тип объекта слишком специфичен.
Как мы жили раньше
В общем случае мы в команде создавали данные для тестов следующим образом:
- Объявлили в каком-то файле утилиты для создания объектов
fun createSomeDifficultClass(): DifficultClass { return DifficultClass( id = ObjectId(), someParam = "test", .... ) }
такие файлики в среднем занимают по 120-200 строчек, но когда ваше апи слишком большое получается много лишнего кода и писать его не очень весело.
- Тест выглядит примерно так
@Test fun test() { val difficultClass = createSomeDifficultClass() ... }
Как мы заживем теперь
Теперь подключив либу, вам не надо больше писать функции для создания объектов, все что нужно это расширить класс расширением библиотеки, данные она сгенерирует за вас.
@ExtendWith(GenerateParameterResolver::class)
class YourTestClass {
@Test
fun test(@Generate difficultClazz) {
...
}
}
Теперь о фичах, библиотека генерирует валидные данные основываясь на javax
data class YourClass(
@field:Null
var param: String?
)
В данном случае, либа увидит аннотацию Null и вызовет соответствующий генератор для нее и param проинициализируется null значением.
Что делать со своими аннотациями?
Библиотеку можно расширять для своих аннотаций, делается это следующим образом, предположим что у нас есть аннотация ValidObjectId, которая проверяет, что строка является id-шником монги, тогда генератор под такую аннотацию будет выглядеть следующим образом:
@ResolverFor(ValidObjectId::class)
class ValidObjectIdGenerator : ValidationParamResolver {
override fun <T> process(generatedParam: T?, clazz: KClass<*>, type: KType, annotation: Annotation): Any? {
return ObjectId().toHexString()
}
}
Мой тип содержит конструктор с некоторой валидацией
Библиотеке можно указать использовать конструктор для конкретного типа
class ObjectIdConstructor : ValidationConstructor<ObjectId> {
override fun call(): ObjectId {
return ObjectId()
}
}
она его подхватит и не будет пытаться самостоятельно генерировать тип.
Как генератору найти мои расширения?
Для этого необходимо навешать на класс аннотацию с путем
@SpringTestDataGenerator(value = "ru.kontur.spring.test.generator")
Вместо вывода
Недавно один друг подсказал, что это похоже на autofixture с c#, но только со своими примочками, что ж будем двигаться в этом направлении.
[Ссылка на репу] (https://github.com/skbkontur/spring-test-data-generator)