2009-06-12 14 views
23

Factory Girl to poręczna ramka do łatwego tworzenia instancji modeli do testowania.Czy framework dla architektury Java istnieje dla Java?

Z Factory Girl home page:

factory_girl pozwala szybko określić prototypów dla każdego z modeli i poprosić o przypadkach o właściwościach, które są ważne do badania pod ręką.

przykład (także ze strony internetowej)

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 

jeśli potrzebny jest użytkownikowi może to wywołać

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

która dostarczy użytkownikowi wszystkich właściwości podanych w prototyp fabryczny, z wyjątkiem dla właściwości administracyjnej, którą podałem jawnie. Zauważ również, że metoda fabryki wiadomości e-mail przynosi inny e-mail za każdym razem, gdy zostanie wywołana.

Myślę, że powinno być całkiem łatwo zaimplementować coś podobnego do Javy, ale nie chcę wymyślać koła.

P.S: Wiem o JMocku i EasyMoc, ale nie mówię tutaj o szyderczym systemie.

+0

Czy możesz podać nam przykład FactoryGirl, bez konieczności ciągłego czytania o tym w innym miejscu? – skaffman

+1

Była jedna dla Pythona, dopóki te związki prawnicze frakcji nie zaczęły wchodzić w drogę! –

+0

Beanmother https://github.com/keepcosmos/beanmother jest tym, czego potrzebujesz. –

Odpowiedz

5

Jedną z możliwych bibliotek do wykonania tej czynności jest Usurper.

Jednakże, jeśli chcesz określić właściwości tworzonych obiektów, wówczas statyczne pisanie Javy sprawia, że ​​struktura staje się bezcelowa. Trzeba będzie określić nazwy właściwości jako łańcuchy, aby struktura mogła wyszukać dodatki do właściwości za pomocą refleksji lub introspekcji Java Bean. To znacznie utrudniałoby refaktoryzację.

O wiele łatwiej jest po prostu rozwinąć obiekty i wywołać ich metody. Jeśli chcesz uniknąć wielu kodów w testach, może pomóc wzór Test Data Builder.

+0

Dobrze powiedziawszy - zaakceptowałbym tę odpowiedź, gdyby to było moje pytanie. :) – cwash

+1

[Ułatw sobie] (http://code.google.com/p/make-it-easy/) jest w pewien sposób podobny, ponieważ pomaga w implementacji Konstruktorów danych testowych, które definiują wartości domyślne dla każdej właściwości. – Augusto

+0

Link uzurpatora jest uszkodzony, projekt wydaje się być martwy. –

-1

Jeśli twoje obiekty modelu są proste, nie ma powodu, aby używać ram do ich tworzenia, wystarczy użyć operatora "nowego". Jeśli masz złożony model (kompleks relacji), a następnie można użyć sprężynę powiązać je ze sobą (nawet w scenariuszach testowych można użyć wiosna)

  • ale to jest po prostu dla obiektów danych, jeśli mówimy o uruchamianiu obiektów które robią coś, jego zalecane jest pozorowanie/niedopuszczenie zewnętrznych relacji zamiast używania prawdziwych instancji.
+0

"Jeśli twoje modelowe obiekty są proste" Nie są :-) "Możesz użyć sprężyny, aby związać je razem" Czy możesz trochę na to popracować? Załóżmy, że mam model filmu, film ma wiele strumieni, każdy strumień ma hosta. Teraz chciałbym 25 filmów do celów testowych. Jak Spring pomaga mi? Co zrobić, jeśli potrzebuję 25 filmów w bazie danych, aby przetestować moje wyszukiwania? – KaptajnKold

+0

Nie polecam próby budowania ich za pomocą słowa kluczowego "new" dla obiektów o dowolnej złożoności. Przynajmniej chciałbyś użyć wzorca Object Mother (zasadniczo tworzy statyczne metody fabryczne dla często inicjowanych obiektów), ale najlepiej używałbyś wzorca Buildera, ponieważ zapewnia on rozsądne wartości domyślne i mechanizm do przesłonięcia właściwości na poziomie szczegółowym. – cwash

+0

Myślę, że mieszacie tutaj zbyt wiele rzeczy. - Do testowania kodu bazy danych, masz na przykład DBUnit, który pomaga zarządzać testem przed/po bazie danych. - do testu jednostkowego nie potrzebujesz 25 filmów, 2 ore 3 wystarczy, aby UNIT przetestować klasę. Moja opinia jest ... spróbuj uprościć swoje testy, a zobaczysz, że nie potrzebujesz ramy do budowania danych wejściowych do testu. – silmx

2
  1. Rozumiem, to nie jest dla każdego, ale mógłby napisać Ruby kodu testowego przed kodzie Javy. (JTestR)
  2. Preferowanym sposobem wykonania tej czynności w języku Java jest użycie wzoru Test Data Builder. Twierdzę, że takie podejście w rzeczywistości nie uzasadnia wprowadzenia złożoności struktury lub zależności zewnętrznej. Po prostu nie rozumiem, w jaki sposób można określić znacznie mniej przy użyciu frameworka i uzyskać z niego coś więcej ... Składnia Builder jest zasadniczo odpowiednikiem składni FactoryGirl. (Ktoś krępuj się przekonać mnie inaczej!)
1

wiem, że to nie jest dokładnie to, czego szukasz ...

I przeszłość Pisałem jakiś kod, który przy użyciu odbicia do wypełnienia wartości fasoli. Podstawową ideą jest znalezienie wszystkich seterów i wywołanie każdego z fałszywymi wartościami. Moja wersja ustawiła wszystkie ciągi znaków, ponieważ nazwa pola setName zostanie wywołana z "name", następnie ustaw wszystkie int jako 1, booleans na true itd.

Użyłem tego w połączeniu z wzorami podobnymi do Object mother i Tester danych testowych.

Zapewnia dobry początek danych testowych, a wszelkie pola, które wymagają określonych wartości, można jawnie ustawić jako część testu.

Mam nadzieję, że to pomoże.

19

Szukałem także odpowiednika Factory Girl w języku Java, ale nigdy nie znalazłem czegoś podobnego. Zamiast tego stworzyłem rozwiązanie od zera. Fabryka do generowania modeli w Javie: Model Citizen.

Zainspirowany Dziewczyna z fabryki, używa adnotacji pola, aby ustawić wartości domyślne dla modelu, 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(); 
} 

Byłby to Blueprint do tego modelu samochodu. To jest zarejestrowana w ModelFactory, niż nowe instancje mogą być tworzone w następujący sposób:

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

Można zastąpić wartości modelu samochodu przez przechodzącą w instancji Car zamiast klasy i ustawiania wartości w zależności od potrzeb:

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

Ma bardziej złożone przykłady (such as using @Mapped) oraz szczegóły dotyczące kilku innych dzwonków i gwizdów.

1

Przybyłem tutaj z tym samym pytaniem i potrzebowałem do narzędzia do generowania danych dla moich testów integracyjnych. Postanowiłem zaakceptować wyzwanie z Groovy, który jest moim językiem wyboru do testów ze względu na jego zwartość i power assert.

Właśnie napisałem małą pomocnika https://gist.github.com/pgaertig/9502960 o nazwie FactoryGrill;), która pozwala pisać skrypty danych, jak poniżej.

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

powyżej jest równoznaczne z:

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

Można zrobić więcej z 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 

To nie jest fabrycznie naprawdę ponieważ fabryki są dość proste w Groovy z map constructor lub expandos .

Referencje i inne rzeczy z FactoryGirl nie są obecnie dostępne, ponieważ powyższe jest osiągane tylko przy ~ 30LOC. Jednak jeśli istnieje zainteresowanie moim rozwiązaniem, dodam, że zrobię dedykowany projekt na Github.