factory_girl i asocjacje - czy robię coś nie tak?

Dotychczas modele w testach tworzyłem… niezbyt zgrabną metodą. Dzisiaj do testów w steaku dodałem factory_girl, jednak chyba nie do końca wiem, czy używam tego dobrze.

Otóż przyjmijmy, że w spec/factories.rb mamy coś takiego:

Factory.define :user do |f| f.email "test@rubyonrails.org" f.password "dupa.8" f.password_confirmation "dupa.8" end

Super. Następnie w jednym z plików ze spec/acceptance mamy:

[code Ruby] before(:all) do
@current_user = Factory :user
end

before(:each) do
log_in
end

after(:each) do
log_out
end[/code]

…i odpowiednie helpery w spec/acceptance/support/helpers.rb:

[code Ruby] def log_in
visit ‘/users/sign_in’

fill_in 'user_email', :with => @current_user.email
fill_in 'user_password', :with => @current_user.password
click_button 'Sign in'

end

def log_out
visit ‘/users/sign_out’
end[/code]

Wiem, że mógłbym zrobić to nieco krócej, ale tak jest po prostu czytelniej i bardziej logicznie.

Załóżmy, że napisaliśmy już scenariusz, w którym to dodajemy nowy artykuł. W następnych scenariuszach (edycja, usuwanie) nie ma sensu powtarzać tego związanego z dodawaniem, więc po prostu sięgamy do factory_girl:

[code Ruby]# factories.rb
Factory.define :article do |f|
f.title “Herp derp”
f.content “Lorem ipsum dolor sit amet…”
f.association :user
end

jeden z plików w spec/acceptance

tego helpera użyjemy tylko w nim, więc chyba nie ma sensu umieszczać go w support/helpers.rb

def add_article
@article = Factory(:article)
end
[/code]

I tutaj właśnie leży mój problem. factory_girl próbuje jeszcze raz stworzyć powiązane z modelem obiekty. W tym przypadku znów spróbuje utworzyć usera, chociaż ten już istnieje. Oczywiście spowoduje to błąd. Obszedłem to poprzez usunięcie asocjacji w pliku factories.rb i zmianę linijki w add_article:

def add_article @article = Factory(:article, :user => @current_user) end

…ale nie jestem pewien, czy “robię to dobrze”, czy coś skopałem (lub o czymś nie wiem) i istnieje prostszy sposób, więc byłoby miło, gdyby ktoś wypowiedział się na ten temat.

Ja zostawiam asocjację w definicji Factory :user i w razie potrzeby przekazuję parametr tak jak Ty:

@article = Factory(:article, :user => @current_user)

Ma to sens - jeśli nie obchodzi mnie user, to niech zostanie utworzony rekord tak żeby model był kompletny, ale jeśli zależy mi na tym, żeby to był ten user a nie inny to przekazuję go w parametrach.