28 Stimmen

Gibt es ein Framework wie Factory Girl für Java?

Factory Girl ist ein praktisches Framework in Rails zur einfachen Erstellung von Instanzen von Modellen für Tests.

Von der Factory Girl-Startseite :

factory_girl ermöglicht es Ihnen, schnell Prototypen für jedes Ihrer Modelle zu definieren und nach Instanzen mit Eigenschaften zu fragen, die für den jeweiligen Test wichtig sind.

Ein Beispiel (auch von der Homepage):

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

wenn ich einen Benutzer brauche, kann ich einfach aufrufen

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

was einen Benutzer mit allen im Prototyp der Fabrik angegebenen Eigenschaften ergibt, außer für die Admin-Eigenschaft, die ich explizit angegeben habe. Beachten Sie auch, dass die E-Mail-Fabrik-Methode jedes Mal, wenn sie aufgerufen wird, eine andere E-Mail liefern wird.

Ich denke, es sollte ziemlich einfach sein, etwas Ähnliches für Java zu implementieren, aber ich möchte das Rad nicht neu erfinden.

P.S.: Ich kenne sowohl JMock als auch EasyMoc, aber ich spreche hier nicht von einem Mocking Framework.

22voto

mguymon Punkte 8826

Ich habe auch nach einem Java-Äquivalent zu Factory Girl gesucht, aber nie etwas Ähnliches gefunden. Stattdessen habe ich eine Lösung von Grund auf neu entwickelt. Eine Fabrik zur Erzeugung von Modellen in Java: Muster-Bürgerin .

Inspiriert von Factory Girl, verwendet es Feldkommentare, um Standardwerte für ein Modell festzulegen, ein einfaches Beispiel aus dem 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();
}

Dies wäre die Blaupause für das Automodell. Dieses wird in der ModelFactory registriert, dann können neue Instanzen wie folgt erstellt werden:

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

Sie können die Werte des Car-Modells außer Kraft setzen, indem Sie eine Instanz von Car anstelle der Klasse übergeben und die Werte nach Bedarf einstellen:

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

En wiki hat komplexere Beispiele ( wie die Verwendung von @Mapped ) und Details für ein paar weitere Extras.

8voto

Nat Punkte 9604

Eine mögliche Bibliothek für diese Zwecke ist Usurpator .

Wenn Sie jedoch die Eigenschaften der Objekte, die Sie erstellen, angeben wollen, macht die statische Typisierung von Java ein Framework überflüssig. Sie müssten die Eigenschaftsnamen als Strings angeben, damit das Framework mithilfe von Reflection oder Java Bean Introspection nach Eigenschaftszugriffsmöglichkeiten suchen kann. Das würde das Refactoring erheblich erschweren.

Es ist viel einfacher, die Objekte einfach neu zu erstellen und ihre Methoden aufzurufen. Wenn Sie in den Tests eine Menge Standardcode vermeiden wollen, können Sie die Test Data Builder Muster kann helfen.

2voto

cwash Punkte 4055
  1. Ich verstehe, dass das nicht für jeden etwas ist, aber Sie könnte Ruby-Testcode gegen Ihren Java-Code schreiben. (JTestR)
  2. Der bevorzugte Weg, dies in Java zu tun, ist die Verwendung der Test Data Builder Muster. Ich würde argumentieren, dass dieser Ansatz nicht wirklich die Einführung der Komplexität eines Rahmens oder einer externen Abhängigkeit rechtfertigt. Ich sehe einfach nicht, wie man mit einem Framework viel weniger spezifizieren und mehr herausholen könnte... die Builder-Syntax ist im Wesentlichen äquivalent zu Ihrer FactoryGirl-Syntax. (Jemand kann mich gerne vom Gegenteil überzeugen!)

1voto

Pablojim Punkte 8312

Ich weiß, das ist nicht genau das, wonach Sie suchen...

Ich habe in der Vergangenheit einige Codes geschrieben, die mit Reflexion eine Bohne Werte zu befüllen. Die Grundidee ist, alle Setter zu finden und jeden mit einem Dummy-Wert aufzurufen. Meine Version setzen alle Strings als den Namen des Feldes setName würde mit "Name" aufgerufen werden, dann setzen Sie alle ints als 1, Boolesche auf wahr usw.

Ich habe dies dann in Verbindung mit den Mustern ähnlich wie bei Object mother und Test Data Builder verwendet.

Sie bot einen guten Ausgangspunkt für Testdaten, und alle Felder, die bestimmte Werte erforderten, konnten im Rahmen des Tests explizit festgelegt werden.

Ich hoffe, das hilft.

1voto

gertas Punkte 16291

Ich bin hier mit der gleichen Frage angekommen und benötige ein Werkzeug zur Datengenerierung für meine Integrationstests. Ich entschied mich, die Herausforderung mit Groovy anzunehmen, da diese Sprache aufgrund ihrer Kompaktheit und ihrer Flexibilität die Sprache meiner Wahl für Tests ist. Machtanspruch .

Ich habe gerade ein kleines Hilfsprogramm geschrieben https://gist.github.com/pgaertig/9502960 namens FactoryGrill ;), mit dem Sie Datenskripte wie das folgende schreiben können.

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

ist gleichbedeutend mit:

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

Mit Groovy kann man mehr machen:

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

Es ist nicht wirklich eine Fabrik, denn Fabriken sind in Groovy ziemlich einfach mit Kartenkonstrukteur o expandos .

Referenzen und andere Dinge von FactoryGirl sind derzeit nicht verfügbar, weil oben nur mit ~30LOC erreicht wird. Allerdings, wenn es ein Interesse an meiner Lösung werde ich hinzufügen, machen ein eigenes Projekt auf Github.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X