2009-06-12 9 views
23

Factory Girl es un práctico marco en rieles para crear fácilmente instancias de modelos para probar.¿Existe un framework como Factory Girl para Java?

Desde el Factory Girl home page:

factory_girl le permite definir rápidamente prototipos para cada uno de sus modelos y pedir instancias con propiedades que son importantes para la prueba en cuestión.

Un ejemplo (también desde la página principal):

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 

si necesito un usuario de un solo pueden llamar

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

que producirá un usuario con todas las propiedades especificadas en el prototipo de fábrica, excepto para la propiedad de administrador que he especificado explícitamente. También tenga en cuenta que el método de fábrica de correo electrónico arrojará un correo electrónico diferente cada vez que se llame.

Estoy pensando que debería ser bastante fácil implementar algo similar para Java, pero no quiero reinventar la rueda.

P.S: Conozco tanto a JMock como a EasyMoc, pero no estoy hablando de un marco de burla aquí.

+0

¿Puede darnos un ejemplo de FactoryGirl, sin tener que ir y leer sobre él en otro lugar? – skaffman

+1

¡Había uno para Python hasta que los sindicatos de derechos de los armadores empezaron a ponerse en el camino! –

+0

Beanmother https://github.com/keepcosmos/beanmother es lo que quieres. –

Respuesta

5

Una posible biblioteca para hacer esto es Usurper.

Sin embargo, si desea especificar las propiedades de los objetos que está creando, la tipificación estática de Java hace que el marco no tenga sentido. Tendría que especificar los nombres de las propiedades como cadenas para que el marco pueda buscar los accesos a las propiedades mediante la reflexión o introspección de Java Bean. Eso haría la refactorización mucho más difícil.

Es mucho más simple simplemente actualizar los objetos y llamar a sus métodos. Si desea evitar muchos códigos repetitivos en las pruebas, el patrón Test Data Builder puede ayudar.

+0

Bien dicho - Aceptaría esta respuesta si fuera mi pregunta. :) – cwash

+1

[Make it easy] (http://code.google.com/p/make-it-easy/) es de alguna manera similar, ya que ayuda a implementar Test Data Builders, que define los valores predeterminados para cada propiedad. – Augusto

+0

El enlace usurpador está roto, el proyecto parece estar muerto. –

-1

Si los objetos de su modelo son simples, no hay razón para usar un marco para crearlos, simplemente use el operador 'nuevo'. Si tiene complejo modelo (relaciones complejas) entonces se puede usar un muelle para atarlos juntos (incluso en escenarios de prueba se puede usar un muelle)

  • pero esto es simplemente para objetos de datos, si usted está hablando de crear instancias de objetos que están haciendo algo, se recomienda simular/resguardar las relaciones externas en lugar de usar instancias reales.
+0

"Si los objetos de su modelo son simples" No son :-) "puede usar la primavera para unirlos" ¿Puede eloborar un poco sobre eso? Digamos que tengo un modelo de película, la película tiene varias transmisiones, cada transmisión tiene un anfitrión. Ahora me gustaría tener 25 películas para realizar pruebas. ¿Cómo me ayuda Spring? ¿Qué pasa si necesito 25 películas en la base de datos para probar mis métodos de búsqueda? – KaptajnKold

+0

No recomendaría intentar construir estos usando la palabra clave 'nueva' para objetos de cualquier complejidad. Por lo menos, querrá utilizar el patrón Object Mother (básicamente crear métodos de fábrica estáticos para objetos comúnmente inicializados), pero idealmente usaría el patrón Builder porque le proporciona valores predeterminados y un mecanismo para anular las propiedades en un nivel granular. – cwash

+0

Creo que estás mezclando demasiadas cosas aquí. - Para las pruebas de código de base de datos, tiene DBUnit, por ejemplo, que lo ayuda a administrar la prueba previa/posterior de la base de datos. - para una prueba unitaria no necesitarás 25 películas, 2 o 3 son suficientes para que UNIT pruebe la clase. Mi opinión es ... intente simplificar sus pruebas, y verá que no necesita un marco para construir la entrada para la prueba. – silmx

2
  1. entiendo que esto no es para todo el mundo, pero que podría escribir código de prueba de Ruby en contra de su código Java. (JTestR)
  2. La forma preferida de hacer esto en Java es usando el patrón Test Data Builder. Yo argumentaría que este enfoque realmente no garantiza la introducción de la complejidad de un marco o dependencia externa. Simplemente no veo cómo podría especificar mucho menos el uso de un marco y obtener algo más de eso ... la sintaxis del Constructor es esencialmente equivalente a su sintaxis FactoryGirl. (Que alguien se sienta libre de convencerme de lo contrario!)
1

Sé que esto no es exactamente lo que está buscando ...

que el pasado he escrito algo de código que el uso de la reflexión para rellenar una valores de frijoles La idea básica es encontrar todos los setters y llamar a cada uno con un valor ficticio. Mi versión establece todas las cadenas como el nombre del campo setName se llamaría con "nombre", luego establecer todas las entradas como 1, booleanos a verdadero, etc.

Luego utilicé esto en conjunto con los patrones similares a Objeto madre y Test Data Builder.

Proporcionó un buen comienzo para los datos de prueba y cualquier campo que requiriera valores específicos podría establecerse explícitamente como parte de la prueba.

Espero que esto ayude.

19

También busqué un equivalente Java de Factory Girl, pero nunca encontré nada igual. En cambio, creé una solución desde cero. Una fábrica para generar modelos en Java: Model Citizen.

Inspirado por Factory Girl, que utiliza las anotaciones de campo para establecer los valores predeterminados para un modelo, 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(); 
} 

Este sería el modelo para el modelo del coche. Esto se ha registrado en el ModelFactory, que los nuevos se pueden crear instancias de la siguiente manera:

ModelFactory modelFactory = new ModelFactory(); 
modelFactory.registerBlueprint(CarBlueprint.class); 
Car car = modelFactory.createModel(Car.class); 

Puede anular los valores del modelo de coche al pasar en una instancia de coches en lugar de la clase y el establecimiento de los valores según sea necesario:

Car car = new Car(); 
car.setMake("mustang"); 
car = modelFactory.createModel(car); 

El wiki tiene ejemplos más complejos (such as using @Mapped) y detalles de un poco más de campanas y silbatos.

1

Llegué aquí con la misma pregunta y necesitaba una herramienta de generación de datos para mis pruebas de integración. Decidí aceptar el desafío con Groovy, que es mi lenguaje de elección para las pruebas debido a su tamaño compacto y power assert.

Acabo de escribir un pequeño ayudante https://gist.github.com/pgaertig/9502960 llamado FactoryGrill;) que le permite escribir los scripts de datos como a continuación.

insert('MyTable', ID: 1, CREATED_AT: new Date(), NAME: 'Example text') 

anterior es equivalente a:

INSERT INTO MyTable(ID, CREATED_AT, NAME) VALUES (1, ..current date here.., 'Example text') 

se puede hacer más con 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 

No es la fábrica de verdad porque las fábricas son bastante sencillo en Groovy con map constructor o expandos .

Las referencias y otras cosas de FactoryGirl no están disponibles actualmente porque arriba solo se logra con ~ 30LOC. Sin embargo, si hay un interés en mi solución, agregaré un proyecto dedicado en Github.

Cuestiones relacionadas