Il mio secondo articolo su questa gemma Ruby popolare e utile si occupa di un paio di argomenti più sfumati che i principianti non hanno necessariamente bisogno di preoccuparsi subito quando iniziano. Ancora una volta, ho fatto del mio meglio per mantenerlo accessibile ai principianti e spiegare ogni frammento di gergo nuovo a Test-Driven Development (TDD) potrebbe inciampare.
Se hai bisogno di usare i valori degli attributi per comporre al volo gli altri attributi di fabbrica, Factory Girl ti copre. Hai solo bisogno di racchiudere il valore dell'attributo in un blocco e di interpolare gli attributi di cui hai bisogno. Questi blocchi hanno accesso a un valutatore-che è ceduto a loro - e che a sua volta ha accesso ad altri attributi, anche transitori.
FactoryGirl.define do factory: supervillain do name 'Karl Stromberg' passione 'biologia marina' ambizione 'estinzione umana' motivazione 'salva il profilo degli oceani' "# nome ha una passione per # passione e punta a # motivazione attraverso # ambition. " end end villain = create (: supervillain) villain.profile # =>" Karl Stromberg ha una passione per la biologia marina e mira a salvare gli oceani attraverso l'estinzione umana. "
Penso sia giusto chiamarli attributi falsi. Questi attributi virtuali ti consentono anche di passare opzioni aggiuntive quando costruisci le tue istanze di fabbrica, ovviamente tramite un hash. L'istanza stessa non ne sarà influenzata poiché questi attributi non saranno impostati sull'oggetto factory. D'altra parte, Factory Girl tratta gli attributi transienti proprio come quelli reali.
Se usi attributes_for
, non si presenteranno però. Attributi dipendenti e callback sono in grado di accedere a questi attributi falsi all'interno della tua fabbrica. Nel complesso, sono un'altra strategia per mantenere le vostre fabbriche ASCIUTTE.
FactoryGirl.define do factory: supervillain do transient do megalomane false cat_owner nome falso nome 'Karl Stromberg' passione 'biologia marina' ambizione 'estinzione umana' motivazione "Costruire una civiltà subacquea # " e salvare il mondo "se megalomane" profilo "Insane business tycoon # " - amici con Blofeld "if cat_owner" end end villain = create (: supervillain) villain.profile # => "Insane business tycoon" villain.motivation # => "Costruire una civiltà sottomarina "cat_friendly_villain = create (: supervillain, cat_owner: true) cat_friendly_villain.profile # =>" Il magnate degli affari folle - amici di Blofeld "narcissistic_villain = create (: supervillain, megalomane: true) narcissistic_villain.motivation # =>" Costruire una civiltà subacquea e salvare il mondo "
L'esempio sopra risulta essere un po 'più SECCO poiché non c'era bisogno di creare fabbriche separate per i supercriminali che vogliono salvare il mondo o sono amici di Blofeld rispettivamente. Gli attributi transitori ti danno la flessibilità di effettuare tutti i tipi di regolazioni ed evitare di creare una serie di fabbriche sempre così simili.
Gli attributi "normali" in Factory Girl vengono valutati al momento della definizione della fabbrica. Di solito fornisci valori statici come parametri ai metodi con lo stesso nome dei tuoi attributi. Se si desidera ritardare la valutazione fino all'ultimo istante possibile, quando l'istanza viene istanziata, sarà necessario alimentare gli attributi con i relativi valori tramite un blocco di codice. Associazioni e valori creati dinamicamente da oggetti come Appuntamento
gli oggetti saranno i tuoi clienti più frequenti per quel trattamento pigro.
FactoryGirl.define do factory: exploding_device do transient do countdown_seconds 10 * 60 time_of_explosion Time.now + countdown_seconds end time_of_explosion "Esplode in # countdown_seconds secondi # time_of_explosion.strftime (" in% I:% M% p ") " end end ticking_device = create (: exploding_device) ticking_device.time_of_explosion # =>" Esplodendo in 600 secondi alle 23:53 PM "
Questo probabilmente non è un caso d'uso in cui ti imbatterai ogni giorno, ma a volte erediti fabbriche da altri sviluppatori e vuoi cambiarle, nel caso in cui tu stia usando una gemma di TDD per esempio. Se senti la necessità di modificare queste fabbriche legacy per adattarle meglio ai tuoi specifici scenari di test, puoi modificarle senza crearne di nuove o utilizzare l'ereditarietà.
Lo fai via FactoryGirl.modify
, e deve essere al di fuori di quel particolare FactoryGirl.define
blocco che si desidera modificare. Quello che non puoi fare è modificare sequenza
o tratto
-puoi sovrascrivere gli attributi definiti tramite tratto
anche se. Anche le callback sulla factory "originale" non verranno sovrascritte. Il callback nel tuo Factory.modify
il blocco verrà eseguito come il prossimo in linea.
FactoryGirl.define do factory: spy do name 'Marty McSpy' skills 'Spionage and infiltration' deployment_status 'Fine missione di preparazione' FactoryGirl.modify do sequence: mission_deployment do | number | "Missione # numero a # DateTime.now.to_formatted_s (: short)" end factory: spy do name 'James Bond' skills 'CQC e poker' favorite_weapon 'Walther PPK' body_count 'Classified' favorite_car 'Aston Martin DB9 'deployment generate (: mission_deployment) fine
Nell'esempio sopra, avevamo bisogno che le nostre spie fossero un po 'più "sofisticate" e usassero un meccanismo migliore per gestire l'implementazione. Ho visto esempi in cui gli autori delle gemme hanno dovuto affrontare il tempo in modo diverso e dove è stato utile modificare gli oggetti di fabbrica semplicemente ignorando le cose che è necessario modificare.
Le callback ti permettono di iniettare del codice in vari momenti del ciclo di vita di un oggetto salvare
, after_save
, before_validation
e così via. Rails, ad esempio, offre un sacco di loro e rende piuttosto facile per i principianti abusare di questo potere.
Tieni presente che i callback che non sono correlati alla persistenza degli oggetti sono noti anti-pattern ed è un buon consiglio non superare quella linea. Ad esempio, può sembrare conveniente utilizzare una richiamata dopo aver istanziato qualcosa come l'utente per inviare e-mail o elaborare un ordine, ma questo tipo di cose invitano bug e creano legami che sono inutilmente difficili da refactoring. Forse questo è stato uno dei motivi per cui Factory Girl "only" ti offre cinque opzioni di callback con cui giocare:
prima (: creare)
esegue un blocco di codice prima che l'istanza di fabbrica venga salvata. Attivato quando si usa creare (: some_object)
.dopo (: creare)
esegue un blocco di codice dopo aver salvato l'istanza di fabbrica. Attivato quando si usa creare (: some_object)
.dopo (: build)
esegue un blocco di codice dopo che l'oggetto factory è stato creato in memoria. Attivato quando si usano entrambi costruire (: some_object)
e creare (: some_object)
.dopo (: stub)
esegue un blocco di codice dopo che la fabbrica ha creato un oggetto stubato. Attivato quando si usa build_stubbed (: some_object)
.personalizzato (: your_custom_callback)
esegue una richiamata personalizzata senza la necessità di anteporre prima
o dopo
.FactoryGirl.define do factory: mission do obiettivo 'Stopping the bad dude' provided_gadgets 'Mini sottomarino e pistola di squalo' dopo (: build) assign_support_analyst end end
Si noti che per tutte le opzioni di callback, all'interno dei blocchi di callback, si avrà accesso a un'istanza della fabbrica tramite un parametro di blocco. Questo sarà utile ogni tanto, specialmente con le associazioni.
FactoryGirl.define fa factory: double_agent do after (: stub) | double_agent | assign_new_identity (double_agent) end end
Sotto, un ninja ha a sua disposizione un mucchio di brutti stelle da lancio (shuriken). Dal momento che hai un ninja
oggetto nella richiamata, è possibile assegnare facilmente la stella che gira per appartenere al Ninja. Dai un'occhiata alla sezione su associazioni se quell'esempio ti lascia un paio di punti interrogativi.
FactoryGirl.define do factory: ninja do name "Ra's al Ghul" factory: ninja_with_shuriken do transient do number_of_shuriken 10 end after (: create) do | ninja, valutatore | create_list (: shuriken, Evaluator.number_of_shuriken, ninja: ninja) end end end factory: shuriken do name 'Hira-shuriken' number_of_spikes 'Four' ninja end end ninja = crea (: ninja) ninja.shurikens.length # => 0 ninja = create (: ninja_with_shuriken) ninja.shurikens.length # => 10 ninja = create (: ninja_with_shuriken, number_of_shuriken: 20) ninja.shurikens.length # => 20
Inoltre, attraverso l'oggetto valutatore hai accesso anche agli attributi transitori. Ciò ti dà la possibilità di passare informazioni aggiuntive quando "crei" oggetti di fabbrica e devi modificarli al volo. Questo ti dà tutta la flessibilità necessaria per giocare con le associazioni e scrivere dati di test espressivi.
Se trovi la necessità di avere più callback sulla tua fabbrica, Factory Girl non ti ostacola, anche di più tipi. Naturalmente, l'ordine di esecuzione è dall'inizio alla fine.
FactoryGirl.define fa factory: lo scagnozzo fa il nome 'Mr. Hinx 'after (: create) | scagnozzo | henchman.send_on_kill_mission dopo (: create) send_cleaner end end
FactoryGirl.define do factory: bond_girl do name 'Lucia Sciarra' after (: build) | bond_girl | bond_girl.hide_secret_documents after (: create) close_hidden_safe_compartment end end
Il diavolo è nei dettagli, ovviamente. Se usi creare (: some_object)
, tutti e due dopo (: build)
e dopo (: creare)
i callback saranno eseguiti.
È possibile raggruppare più strategie di compilazione per eseguire anche la stessa callback.
FactoryGirl.define do factory: spy do name 'Marty McFly' dopo (: stub,: build) | spy | spy.assign_new_mission end end
Ultimo ma non meno importante, puoi anche impostare qualcosa come i callback "globali" che sovrascrivono i callback per tutte le fabbriche, almeno in quel particolare file se li hai separati in più file di fabbrica.
fabbriche / gun.rb
FactoryGirl.define fa prima (: stub,: build,: create) | object | object.assign_serial_number factory: spy_gun do name 'Walther PPK' ammunition '7.65mm Browning' associazione: owner factory: golden_gun do name 'Custom Lazar' munizioni '24 -carat gold car 'dopo (: create) | golden_gun | golden_gun.erase_serial_number fine fine
Se si utilizza l'ereditarietà per comporre fabbriche secondarie, anche i callback sul genitore verranno ereditati.
Portiamo tutto insieme nelle seguenti sezioni su associazioni e tratti-sì, mi sono intrufolato anche io alias perché era il posto migliore senza saltare dappertutto. Se hai prestato attenzione e ricordi roba del primo articolo, ora tutto dovrebbe essere sistemato abbastanza bene.
Le associazioni sono essenziali per ogni app web che si rispetti e che ha un po 'di complessità. Un post che appartiene a un utente, un elenco che ha molte valutazioni e così via sono gli sviluppatori di pane e burro per la colazione in qualsiasi giorno della settimana. Da questa prospettiva, diventa ovvio che per scenari più complessi le fabbriche devono essere a prova di proiettile e facili da maneggiare, almeno per non rovinare il tuo mojo TDD.
Emulare le associazioni di modelli tramite Factory Girl è relativamente semplice, direi. Questo di per sé è abbastanza sorprendente nella mia mente. Raggiungere un elevato livello di facilità e convenienza per la creazione di set di dati complessi rende la pratica del TDD un gioco da ragazzi e molto più efficace.
La nuova Q ha capacità di hacker e ha bisogno di possedere un computer decente, giusto? In questo caso hai un Computer
la classe e le sue istanze appartengono a istanze del furiere
classe. Facile, giusto?
FactoryGirl.define do factory: quartermaster do name 'Q' skills 'Inventing stuff' end factory: computer do model 'Personalizzazione Lenovo ThinkPad serie W' quartermaster end end
Che dire qualcosa di un po 'più coinvolto? Diciamo che le nostre spie usano a pistola
che has_many cartucce
(proiettili).
Cartuccia di classe < ActiveRecord::Base belongs_to :gun end class Gun < ActiveRecord::Base has_many :cartridges end
FactoryGirl.define do factory: cartuccia do calibre '7.65' gun end factory: gun do name 'Walther PPK' munizioni '7.65mm Browning' calibro '7.65' factory: gun_with_ammo do transient do magazine_size 10 end after (: create) do | gun , valutatore | create_list (: cartridge, Evaluator.magazine_size, gun: gun) end end end end
I callback sono abbastanza utili con le associazioni, eh? Ora puoi costruire una pistola con o senza munizioni. Via l'hash pistola: pistola
hai fornito il cartuccia
fabbrica con le informazioni necessarie per creare l'associazione tramite il foreign_key
.
spy_gun = create (: gun) spy_gun.cartridges.length # => 0 spy_gun_with_ammo = crea (: gun_with_ammo) spy_gun_with_ammo.cartridges.length # => 10
Se hai bisogno di un altro formato di rivista, puoi passarlo attraverso il tuo attributo transitorio.
big_magazine_gun = create (: gun_with_ammo, magazine_size: 20) big_magazine_gun.cartridges.length # => 20
Quindi, per quanto riguarda le diverse strategie di costruzione? Non c'era qualcosa di strano? Bene, ecco cosa devi ricordare: se usi creare
per gli oggetti associati, entrambi verranno salvati. Così creare (: furiere)
costruirà e salverà sia Q che il suo ThinkPad.
Farei meglio ad usarlo costruire
, quindi, se voglio evitare di colpire il database, giusto? Buona idea, ma costruire
si applicherebbe solo a furiere
nel nostro esempio, l'associato computer
verrebbe comunque salvato. Un po 'complicato, lo so. Ecco cosa puoi fare se devi evitare di salvare l'oggetto associato: devi specificare la strategia di build necessaria per la tua associazione.
FactoryGirl.define do factory: quartermaster do name 'Q' skills 'Inventing stuff' factory: computer do model 'Personalizzazione Lenovo ThinkPad serie W' associazione: quartermaster, strategia:: build end end
Assegnare un nome all'oggetto factory associato e passare un hash con la strategia di build. Devi usare l'esplicito associazione chiedi che funzioni. L'esempio seguente non funzionerà.
factory: computer do model Quartiermastro 'Custom Lenovo ThinkPad W Series', strategia:: build end
Ora entrambi gli oggetti usano costruire
e niente viene salvato nel database. Possiamo controllare questa ipotesi usando nuovo record?
, che ritorna vero
se l'istanza non è stata mantenuta.
thinkpad = build (: computer) thinkpad.new_record? # => true thinkpad.quartermaster.new_record? # => true
Mentre ci siamo, attraverso l'esplicito associazione chiama puoi anche fare riferimento a diversi nomi di fabbrica e modificare gli attributi al volo.
FactoryGirl.define fa factory: quartermaster do name 'Q' end factory: computer do model 'Personalizzazione Lenovo ThinkPad serie W' associazione: hacker, factory:: quartermaster, skills: 'Hacking' end end
Chiudiamo questo capitolo con un esempio polimorfo.
classe Spy < ActiveRecord::Base belongs_to :spyable, polymorpic: true end class MIFive < ActiveRecord::Base has_many :spies, as: :spyable end class MISix < ActiveRecord::Base has_many :spies, as: :spyable end
FactoryGirl.define do factory: mifive do name 'Military Intelligence, Section 5' principal_activity 'Fine fabbrica di controspionaggio nazionale': misix do name 'Military Intelligence, Section 6' principal_activity 'End counter-intelligence' end factory: mifive_spy, class: Spia do name '005' association: spyable, factory:: mifive end factory: misix_spy, classe: Spy do name '006' associazione: spyable, factory:: misix end end # agenti MI5 mifive = create (: mifive) mifive_spy = create (: mifive_spy) mifive.spies << mifive_spy mifive.name # => "Military Intelligence, Section 5" mifive_spy.name # => '005' mifive.spies.length # => 1 mifive.spies.first.name # => '005' # agenti MI6 misix = create (: misix) misix_spy_01 = crea (: misix_spy, nome: '007') misix_spy_02 = crea (: misix_spy) misix.spies << misix_spy_01 misix.spies << misix_spy_02 misix.name # => "Military Intelligence, Section 6" misix.spies.length # => 2 misix_spy_01.name # => '007' misix_spy_02.name # => '006' misix.spies.first.name # => '007'
Non sentirti male se questo ha bisogno di un po 'più di tempo per affondare. Raccomando di consultare le Associazioni polimorfiche se non sei sicuro di cosa sta succedendo qui.
Gli alias per le tue fabbriche ti consentono di essere più espressivo riguardo al contesto in cui stai utilizzando gli oggetti factory. Devi solo fornire un hash di nomi alternativi che descrivano meglio la relazione tra gli oggetti associati.
Diciamo che hai un :agente
fabbrica e a : law_enforcement_vehicle
fabbrica. Non sarebbe bello fare riferimento all'agente come :proprietario
nel contesto di queste auto? Nell'esempio seguente, l'ho confrontato con un esempio senza un alias.
FactoryGirl.define do factory: agent, aliases: [: owner] do name 'Fox Mulder' lavoro 'Chasing bad dudes' special_skills 'Investigation and intelligence' factory: double_O_seven do name 'James Bond' end end factory: law_enforcement_vehicle do name 'Oldsmobile Achieva 'gentile' Macchina compatta ': proprietario fabbrica finale: spy_car do name' Aston Martin DB9 'tipo' Auto sportiva 'double_O_seven end end
Non dimenticare di aggiungere i due punti davanti alla fabbrica con alias (:proprietario
) quando li usi per le associazioni nelle tue fabbriche. La documentazione e molti post del blog li usano senza due punti in questi casi. Tutto quello che ottieni è probabilmente un NoMethodError
perché ti manca un metodo setter per quell'alias adesso. (Farò meglio ad aprire una richiesta di pull.) La prima volta che mi sono imbattuto in questo, mi ha sconcertato e mi ha preso un po 'per superarlo. Ricorda di sfidare a volte selettivamente documentazione e post sul blog. Cordiali saluti, naturalmente.
Penso che sarete d'accordo che usando gli alias non solo si legge meglio, ma si dà anche a te o alla persona che viene dopo di te un po 'più di contesto sugli oggetti in questione. Sì, devi usare il plurale : alias
anche se hai solo un singolo alias.
Potresti scrivere un po 'diversamente, molto più verbalmente.
factory: agent, aliases: [: mulder] do name 'Fox Mulder' job 'Inseguendo bad dudes' special_skills 'Investigation and intelligence' end factory: law_enforcement_vehicle do name 'Oldsmobile Achieva' kind Associazione 'Compact car': proprietario, fabbrica:: agente fine
Beh, non così pulito, vero??
Ovviamente è possibile utilizzare questi alias anche per "costruire" immediatamente oggetti di fabbrica.
fbi_agent = create (: mulder) fbi_agent.name # => 'Fox Mulder'
Nel contesto dei commenti, a :utente
potrebbe essere indicato come : commentatore
, nel caso di a : il crimine
un :utente
potrebbe essere aliasato come a :sospettare
, e così via. Non è la scienza missilistica in realtà, più come un comodo zucchero sintattico che diminuisce la tentazione per la duplicazione.
Questa è una delle cose che preferisco di Factory Girl. In breve, i tratti sono blocchi di tipo lego per costruire le tue fabbriche e mescolare comportamenti. Sono elenchi separati da virgola di tratti / attributi di simbolo che si desidera aggiungere a un particolare stabilimento e sono anche definiti nei file delle proprie fabbriche.
Nella mia mente, tratto
è la funzione più potente e conveniente per mantenere i dati di fabbrica asciutti pur essendo espressivi allo stesso tempo. Ti consente di raggruppare gruppi di attributi insieme, assegnare loro nomi separati e riutilizzarli dove preferisci. Ti ricordi quando ti ho esortato a definire gli oggetti di fabbrica di bare-bones? I tratti ti aiuteranno a raggiungere esattamente quello senza sacrificare alcuna comodità.
FactoryGirl.define fa factory: spy_car do model 'Aston Martin DB9' top_speed '295 km / h' build_date '2015' ejection_seat true trait: sottomarino do ejection_seat false water_resistant '100 m' submarine_capabilities true air_independent_propulsion true end trait: armati fanno razzi true number_of_rockets '12' machine_gun true rate_of_fire '1.500 RPM' tank_armour vero end trait: cloaked do active_camouflage true radar_signature 'ridotto' engine 'silenced' end trait: night_vision do infrared_sensors true heads_up_display true end end end
Come puoi vedere, se vuoi cambiare alcuni attributi che sono distribuiti su più oggetti, puoi farlo ora in un posto centrale. Non è necessario un intervento chirurgico con fucile a pompa. Gestire lo stato tramite i tratti non potrebbe essere più conveniente.
Con questa configurazione puoi costruire auto da spionaggio piuttosto elaborate mescolando i vari pacchetti di attributi come preferisci, senza duplicare nulla, creando tutti i tipi di nuove fabbriche che rappresentano tutte le varie opzioni di cui hai bisogno.
invisible_spy_car = create (: spy_car,: cloaked,: night_vision) diving_spy_car = create (: spy_car,: submarine,: cloaked) tank_spy_car = create (: spy_car,: weaponized,: night_vision)
Puoi usare i tratti con creare
, costruire
, build_stubbed
e attributes_for
. Se Q diventa intelligente, puoi anche eseguire l'override di singoli attributi contemporaneamente passando un hash.
build (: spy_car,: submarine, ejection_seat: true)
Per le combinazioni di tratti che si verificano molto frequentemente in un particolare stabilimento, puoi anche creare fabbriche di bambini con nomi che rappresentano al meglio le varie combinazioni di set di dati. In questo modo impacchetta le loro caratteristiche solo una volta rispetto a quando crei i dati di test.
FactoryGir.define do factory: spy_car do model 'Aston Martin DB9' top_speed '295 km / h' build_date '2015' ejection_seat true trait: sottomarino do ... end trait: armati do ... end trait: cloaked do ... end trait: night_vision do ... end end factory: invisible_spy_car, tratti: [: cloaked,: night_vision] factory: diving_spy_car, tratti: [: sottomarino,: cloaked] factory: tank_spy_car, tratti: [: weaponized,: night_vision] factory: ultimate_spy_car, tratti: [: cloaked ,: night_vision,: sottomarino,: armata] fine
Questo ti consente di creare questi oggetti in modo più conciso, ed è anche più leggibile.
build_stubbed (: invisible_spy_car) create (: ultimate_spy_car)
Invece di:
build_stubbed (: spy_car,: cloaked,: night_vision) create (: spy_car,: cloaked,: night_vision,: submarine,: weaponized)
Legge molto meglio, no? Soprattutto quando non sono coinvolti nomi di variabili.
Puoi persino riutilizzare i tratti come attributi su altri tratti e fabbriche. Se si definiscono gli stessi attributi per tratti multipli, l'ultimo definito ha la precedenza, ovviamente.
FactoryGirl.define do factory: spy_car do model 'Aston Martin DB9' top_speed '295 km / h' build_date '2015' ejection_seat true trait: sottomarino do ... end trait: armati do ... end trait: cloaked do ... end trait: night_vision do ... end trait: mobile_surveillance do cloaked night_vision signal_detector true signal_analyzer true wifi_war_driver true license_plate_reader true mini_drone vero end end factory: ultimate_spy_car, genitore:: spy_car do car_plane vero sottomarino armato mobile_surveillance end end
Presta attenzione al mobile_surveillance
tratto, che riutilizza il ammantata
e visione notturna
tratti: fondamentalmente come un attributo. Anche il ultimate_spy_car
fabbrica, che ho separato dal spy_car
la definizione di fabbrica per divertimento questa volta, riutilizza tutti i tratti più un attributo aggiuntivo che lo fa volare troppo. Pura magia del film, o forse dovrei dire la magia di Factory Girl.
create_list
e build_list
può anche fare uso di tratti. Il secondo parametro deve essere il numero di istanze di fabbrica che si desidera.
create_list (: spy_car, 3,: night_vision) build_list (: spy_car, 4,: submarine,: cloaked)
Non sarebbe bello usare associazioni con i tratti? Naturalmente è possibile raggruppare in modo ordinato i callback e le associazioni. duh!
FactoryGirl.define do factory: cartuccia do tipo 'Small calibre pistola munizioni' calibro '7.65' proiettile 'piombo' gun factory: golden_cartridge do proiettile 'Gold' associazione: gun,: golden end end factory: pistola do name 'Walther PPK' munizioni '7.65mm Browning' calibro '7.65' transiente do magazine_size 10 end trait: golden do name 'Custom Lazar' munizioni '23 -carat gold bullet 'tratto finale: with_ammo do after (: create) do | gun, valutatore | create_list (: cartridge, valutator.magazine_size, gun: gun) end end trait: with_golden_ammo do after (: create) do | golden_gun, valutatore | create_list (: golden_cartridge, Evaluator.magazine_size, gun: golden_gun) end end end end
Come usarli dovrebbe essere noioso ormai.
cartridge = create (: cartridge) cartridge.projectile # => 'Lead' cartridge.gun.name # => 'Walther PPK' cartridge.gun.ammunition # => '7.65mm Browning' cartridge.gun.caliber # => ' 7.65 'golden_cartridge = create (: golden_cartridge) golden_cartridge.projectile # =>' Gold 'golden_cartridge.gun.name # =>' Custom Lazar 'golden_cartridge.gun.ammunition # => '23 -carat gold car' golden_cartridge.gun.caliber # => '7.65' gun_with_ammo = create (: gun,: with_ammo) gun_with_ammo.name # => 'Walther PPK' gun_with_ammo.ammunition # => '7.65mm Browning' gun_with_ammo.cartridges.length # => 10 gun_with_ammo.cartridges. first.projectile # => 'Lead' gun_with_ammo.cartridges.first.caliber # => '7.65' golden_gun_with_golden_ammo = crea (: gun,: golden,: with_golden_ammo) golden_gun_with_golden_ammo.name # => 'Custom Lazar' golden_gun_with_golden_ammo.ammunition # = > '24 -carat gold bullet 'golden_gun_with_golden_ammo.cartridges.length # => 10 golden_gun_with_golden_ammo.cartridges.first.projectile # =>' Gold ' golden_gun_with_golden_ammo.cartridges.first.caliber # => '7.65'
Ultime parole di saggezza: il cambiamento è il tuo costante compagno, che ha bisogno di cambiare attributi o tipi di dati che si verificano sempre. Le decisioni di progettazione come queste si evolvono. I tratti allevieranno il dolore e ti aiuteranno a gestire i tuoi set di dati.
Immagina se avessi usato un hash di opzioni per l'istanziazione e che il requisito fosse completamente cambiato. Quanti potenziali posti nei tuoi test potrebbero rompersi e ora avranno bisogno di attenzione? Dritto, tratto
è uno strumento molto efficace per eliminare la duplicazione nella tua suite di test. Ma con tutta questa comodità, non essere pigro e dimentica i tuoi test unitari sulle colonne rappresentate dalle tue caratteristiche! In questo modo si danno loro la stessa cura degli attributi di bare-bare necessari per oggetti validi.
C'è un po 'di più da scoprire in Factory Girl, e sono sicuro che ora sei più che ben equipaggiato per mettere insieme i pezzi quando ne hai bisogno. Divertiti a giocare con questa gemma. Spero che le tue abitudini TDD possano trarne beneficio.