2009-06-12 6 views
23

Factory Girl - удобный каркас в рельсах для легкого создания экземпляров моделей для тестирования.Существует ли такая инфраструктура, как Factory Girl для Java?

От Factory Girl home page:

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

Пример (также с домашней страницы):

Factory.sequence :email do |n| 
    "somebody#{n}@example.com" 
end 

# Let's 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 

, если мне нужна пользователю может просто позвонить

test_user = Factory(:user, :admin => true) 

, который даст пользователю со всеми свойствами, указанными в фабричный прототип, за исключением для свойства admin, которое я указал явно. Также обратите внимание, что метод электронной почты по электронной почте будет давать разные электронные письма каждый раз, когда он вызывается.

Я думаю, что должно быть довольно легко реализовать что-то подобное для Java, но я не хочу изобретать велосипед.

P.S: Я знаю обо всех JMock и EasyMoc, однако я не говорю о насмешливой структуре здесь.

+0

Можете ли вы привести нам пример FactoryGirl, без необходимости идти и читать об этом в другом месте? – skaffman

+1

Был один для Python до тех пор, пока профсоюзы прав, основанные на каркасе, не заработали на пути! –

+0

Beanmother https://github.com/keepcosmos/beanmother - это то, что вы хотите. –

ответ

5

Одна возможная библиотека для этого Usurper.

Однако, если вы хотите указать свойства объектов, которые вы создаете, статическая типизация Java делает структуру бессмысленной. Вам нужно будет указать имена свойств в виде строк, чтобы инфраструктура могла искать аксессуры свойств, используя рефлексию или интроспекцию Java Bean. Это сделает рефакторинг намного сложнее.

Это намного проще, чем просто новые объекты и вызвать их методы. Если вы хотите избежать большого количества кода шаблона в тестах, может помочь шаблон Test Data Builder.

+0

Хорошо сказал - я бы принял этот ответ, если бы это был мой вопрос. :) – cwash

+1

[Сделать это легко] (http://code.google.com/p/make-it-easy/) как-то похоже, так как он помогает создавать тестовые сборщики данных, которые определяют значения по умолчанию для каждого свойства. – Augusto

+0

Узурпатор связи сломан, проект кажется мертвым. –

-1

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

  • , но это просто для объектов данных, если вы говорите о инстанцировании объектов которые что-то делают, рекомендуется использовать/отключать внешние отношения вместо использования реальных экземпляров.
+0

«Если ваши объекты модели просты» Их нет :-) «вы можете использовать пружину, чтобы связать их вместе» Можете ли вы немного рассказать об этом? Предположим, у меня есть модель фильма, у фильма есть несколько Потоков, у каждого Стива есть Хост. Теперь мне нужно 25 фильмов для тестирования. Как весна помогает мне? Что делать, если мне нужно 25 фильмов в базе данных, чтобы протестировать мои искатели mehods? – KaptajnKold

+0

Я бы не рекомендовал создавать их с помощью ключевого слова 'new' для объектов любой сложности. По крайней мере, вы захотите использовать шаблон «Маска объекта» (по существу, создавать статические заводские методы для обычно инициализированных объектов), но в идеале вы должны использовать шаблон Builder, потому что он предоставляет вам нормальные значения по умолчанию и механизм переопределения свойств на уровне детализации. – cwash

+0

Я думаю, что вы слишком много смешаете здесь. - Для тестирования кода базы данных у вас есть DBUnit, например, который помогает вам управлять предварительным/пост-тестом базы данных. - для единичного теста вам не понадобятся 25 фильмов, 2 руды 3 достаточно, чтобы выполнить тест UNIT. Мое мнение ... попробуйте упростить свои тесты, и вы увидите, что вам не нужна фреймворк для создания ввода для теста. – silmx

2
  1. Я понимаю, что это не для всех, но вы могли написать тестовый код на Ruby против кода Java. (JTestR)
  2. Предпочтительным способом сделать это в Java является использование шаблона Test Data Builder. Я бы сказал, что этот подход на самом деле не требует введения сложностей каркаса или внешней зависимости. Я просто не понимаю, как вы могли бы указать гораздо меньше, используя фреймворк и получить от него что-то еще ... Синтаксис Builder по сути эквивалентен вашему синтаксису FactoryGirl. (Кто-то не стесняйтесь, чтобы убедить меня в обратном!)
1

Я знаю, что это не совсем то, что вы ищете ...

Я в прошлом я написал некоторый код, с помощью отражения для заполнения бобов. Основная идея состоит в том, чтобы найти все сеттеры и называть каждого с фиктивным значением. Моя версия установила все строки, так как имя поля setName будет вызываться с именем «name», а затем установить все int как 1, booleans на true и т. Д.

Затем я использовал это в сочетании с шаблонами, Создатель тестовых данных.

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

Надеюсь, это поможет.

19

Я также искал Java-эквивалент Factory Girl, но так и не нашел ничего подобного. Вместо этого я создал решение с нуля. Фабрика для генерации моделей в Java: Model Citizen.

Вдохновленный Factory Girl, он использует поля аннотаций для установки по умолчанию для модели, a simple example from the wiki:

@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 = new Car(); 
car.setMake("mustang"); 
car = modelFactory.createModel(car); 

wiki имеет более сложные примеры (such as using @Mapped) и детали еще несколько наворотов.

1

Я пришел сюда с тем же вопросом и был необходим для создания данных для моих интеграционных тестов. Я решил принять вызов с 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 

Это не завод действительно потому, что заводы довольно прямо вперед в Groovy с map constructor или expandos ,

Ссылки и другие материалы от FactoryGirl недоступны в настоящее время, потому что выше достигается только с ~ 30LOC. Однако, если есть интерес к моему решению, я добавлю специальный проект на Github.

 Смежные вопросы

  • Нет связанных вопросов^_^