Существует ли такая платформа, как Factory Girl для Java?
Factory Девушка - удобная структура в рельсах для легкого создания экземпляров моделей для тестирования.
Из Factory Домашняя страница девушки:
factory_girl позволяет быстро определять прототипы для каждой из ваших моделей и запрашивать экземпляры со свойствами, которые важны для теста под рукой.
Пример (также с домашней страницы):
Factory.sequence :email do |n|
"somebody#{n}@example.com"
end
# Let define a factory for the User model. The class name is guessed from the
# factory name.
Factory.define :user do |f|
# These properties are set statically, and are evaluated when the factory is
# defined.
f.first_name 'John'
f.last_name 'Doe'
f.admin false
# This property is set "lazily." The block will be called whenever an
# instance is generated, and the return value of the block is used as the
# value for the attribute.
f.email { Factory.next(:email) }
end
если мне нужен пользователь a, можно просто вызвать
test_user = Factory(:user, :admin => true)
который даст пользователю все свойства, указанные в прототипе Factory, за исключением свойства admin, которое я указал явно. Также обратите внимание, что метод электронной почты Factory будет выдавать другое письмо при каждом вызове.
Я думаю, что было бы довольно легко реализовать что-то подобное для Java, но я не хочу изобретать колесо.
P.S: Я знаю как JMock, так и EasyMoc, однако я не говорю о насмешливой структуре здесь.
Ответы
Ответ 1
Одна из возможных библиотек для этого - Usurper.
Однако, если вы хотите указать свойства объектов, которые вы создаете, то статическая типизация Java делает структуру бессмысленной. Вам нужно будет указать имена свойств в виде строк, чтобы инфраструктура могла искать аксессуры свойств с использованием рефлексии или Java Bean самоанализа. Это сделает рефакторинг намного сложнее.
Это намного проще, чем просто создавать новые объекты и вызывать их методы. Если вы хотите избежать множества шаблонов кода в тестах, может помочь шаблон Test Data Builder.
Ответ 2
Я также искал Java-эквивалент Factory Girl, но так и не нашел ничего подобного. Вместо этого я создал решение с нуля. A Factory для генерации моделей в Java: Model Citizen.
Вдохновленный Factory Girl, он использует аннотации полей для установки значений по умолчанию для модели, простой пример из вики:
@Blueprint(Car.class)
public class CarBlueprint {
@Default
String make = "car make";
@Default
String manufacturer = "car manufacturer";
@Default
Integer mileage = 100;
@Default
Map status = new HashMap();
}
Это будет модель Blueprint для модели автомобиля. Это зарегистрировано в ModelFactory, а новые экземпляры могут быть созданы следующим образом:
ModelFactory modelFactory = new ModelFactory();
modelFactory.registerBlueprint( CarBlueprint.class );
Car car = modelFactory.createModel(Car.class);
Вы можете переопределить значения модели автомобиля, передав экземпляр Car вместо класса и установив значения по мере необходимости:
Car car = new Car();
car.setMake( "mustang" );
car = modelFactory.createModel( car );
wiki содержит более сложные примеры (такие как использование @Mapped) и подробности для еще нескольких колоколов и свистков.
Ответ 3
- Я понимаю, что это не для всех, но вы можете написать тестовый код Ruby против вашего Java-кода. (JTestR)
- Предпочтительный способ сделать это в Java - это использовать шаблон Test Data Builder. Я бы сказал, что этот подход на самом деле не требует введения сложностей каркаса или внешней зависимости. Я просто не понимаю, как вы могли бы указать гораздо меньше, используя фреймворк и получить от него что-то еще... Синтаксис Builder по сути эквивалентен вашему синтаксису FactoryGirl. (Кто-то не стесняется убеждать меня иначе!)
Ответ 4
Я знаю, что это не совсем то, что вы ищете...
В прошлом я написал код, который использует отражение для заполнения значений beans. Основная идея состоит в том, чтобы найти все сеттеры и называть каждого с фиктивным значением. Моя версия установила все строки, так как имя поля setName будет вызываться с именем "name", а затем установить все int как 1, booleans на true и т.д.
Затем я использовал это в сочетании с шаблонами, аналогичными объектам Mother и Test Data Builder.
Это обеспечило хорошее начало тестовых данных, и любые поля, требующие определенных значений, могут быть явно заданы как часть теста.
Надеюсь, что это поможет.
Ответ 5
Я пришел сюда с тем же вопросом и нуждался в инструменте для создания данных для своих тестов интеграции. Я решил принять вызов с Groovy, который является моим языком выбора для тестов из-за его компактности и power assert.
Я только что написал небольшой помощник https://gist.github.com/pgaertig/9502960 под названием FactoryGrill;), который позволяет писать сценарии данных, как показано ниже.
insert('MyTable', ID: 1, CREATED_AT: new Date(), NAME: 'Example text')
выше эквивалентно:
INSERT INTO MyTable(ID, CREATED_AT, NAME) VALUES (1, ..current date here.., 'Example text')
Вы можете сделать больше с помощью Groovy:
import org.apache.commons.lang3.RandomStringUtils;
for ( i in 0..9 ) {
insert('USERS', CREATED_AT: new Date(), EMAIL: "test${i}@mydomain.com",
SALT: RandomStringUtils.randomAlphanumeric(32));
}
load(new File('usersettings.groovy').text) //script nesting etc
Это действительно не factory, потому что фабрики довольно прямолинейны в Groovy с конструктором карты или expandos.
Ссылки и другие материалы от FactoryGirl недоступны в настоящее время, потому что выше достигается только с ~ 30LOC. Однако, если есть интерес к моему решению, я добавлю специальный проект на Github.
Ответ 6
Если ваши объекты модели просты, нет оснований использовать фреймворк для их создания, просто используйте "новый" оператор.
Если у вас сложная модель (сложные отношения), вы можете использовать spring для их связывания (даже в тестовых сценариях вы можете использовать spring)
- но это просто для объектов данных, если вы говорите о создании экземпляров объектов, которые что-то делают, рекомендуется использовать/отключать внешние отношения вместо использования реальных экземпляров.