Jaka jest różnica między metodami kompilacji i tworzenia w programie FactoryGirl?

96

Wprowadzenie do Factory Girl nakreśla różnicę między FactoryGirl.build()i FactoryGirl.create():

# Returns a User instance that's not saved
user = FactoryGirl.build(:user)

# Returns a saved User instance
user = FactoryGirl.create(:user)

Nadal nie rozumiem praktycznych różnic między nimi. Czy ktoś może podać przykład, w którym chciałbyś użyć jednego, a nie drugiego? Dzięki!

Avery
źródło

Odpowiedzi:

120

create()Metoda utrzymuje wystąpienie modelu, podczas gdy build()metoda utrzymuje ją tylko w pamięci.

Osobiście używam tej create()metody tylko wtedy, gdy wytrwałość jest naprawdę konieczna, ponieważ pisanie do DB sprawia, że ​​testowanie jest czasochłonne.

na przykład

Tworzę użytkowników do uwierzytelniania, create()ponieważ mój mechanizm uwierzytelniania wysyła zapytanie do bazy danych.

Aby sprawdzić, czy model ma atrybut, build()metoda zrobi to, ponieważ nie jest wymagany dostęp do bazy danych.

it{Factory.build(:user).should respond_to(:name)}

Aktualizacja

„Jest jeden wyjątek, że build faktycznie 'tworzy' podczas budowania asocjacji, tj. Twoje skojarzenie nie jest już w pamięci, ale trwa. Miej to na uwadze” - Shakes

Helio Santos
źródło
16
Jest jeden wyjątek, że build faktycznie „tworzy” podczas budowania asocjacji, tj. Twoje skojarzenie nie jest już w pamięci, ale trwa. Miej to na uwadze
Shakes
@Shakes, nie pracuję już w szynach. Sprawdzę to najszybciej, jak będę mógł.
Helio Santos
Czy ktoś popełnił narzędzia, aby zastąpić każde wystąpienie createz build, i cofnąć go, jeśli test się nie powiedzie?
mgold
Czy #createodczytuje i zwraca utrwalony obiekt z dysku, czy też zwraca obiekt znajdujący się w pamięci po jego utrwaleniu? Innymi słowy, czy robienie jest create(...)równoważne z create(...).reload?
Dennis
@mgold Vim jest w tym całkiem niezły.
Limited Atonement
15

Używanie FactoryGirl.build(:factory_name)nie jest utrwalane w bazie danych i nie wywołuje save!, więc walidacja modułu Active Record nie będzie działać. Jest to znacznie szybsze, ale walidacja może być ważna.

Użycie FactoryGirl.create(:factory_name)pozostanie w bazie danych i wywoła walidację modułu Active Record. Jest to oczywiście wolniejsze, ale może wychwycić błędy walidacji (jeśli zależy Ci na nich w testach).

przepaść
źródło
11
Lub możesz po prostu zrobić FactoryGirl.build (: nazwa_fabryki) .valid? które uruchamiają walidacje bez zapisywania w bazie danych.
jinavar1
1

FactoryGirl.create()utworzy dla niego nowy obiekt i skojarzenia (jeśli fabryka je posiada). Wszystkie zostaną utrwalone w bazie danych. Spowoduje to również uruchomienie walidacji modelu i bazy danych. Połączenia zwrotne after(:build)i after(:create)zostaną wywołane po zapisaniu ustawień fabrycznych. Również before(:create)zostanie wezwany przed fabryka została zapisana.

FactoryGirl.build()nie zapisze obiektu, ale nadal będzie wysyłać żądania do bazy danych, jeśli fabryka ma skojarzenia. Spowoduje to uruchomienie walidacji tylko dla powiązanych obiektów. Callback after(:build)zostanie wywołany po zbudowaniu fabryki.

Należy pamiętać, że w większości przypadków podczas testowania modeli najlepiej używać w build_stubbedcelu uzyskania lepszej wydajności. Przeczytaj więcej na ten temat tutaj .

Nesha Zoric
źródło