2012-03-13 20 views
5

Sto leggendo attraverso alcuni Rspec scritto da qualcuno che ha lasciato l'azienda. Mi chiedo su questa linea:Qual è il vantaggio di Class.new in questo Rspec

let(:mailer_class) { Class.new(AxeMailer) } 
    let(:mailer) { mailer_class.new } 

    describe '#check' do 
    before do 
     mailer_class.username 'username' 
     mailer.from '[email protected]' 
     mailer.subject 'subject' 
    end 
    subject { lambda { mailer.send(:check) } } 

Si tratta di prove della classe:

class AxeMailer < AbstractController::Base 

    def self.controller_path 
    @controller_path ||= name.sub(/Mailer$/, '').underscore 
    end 

voglio sapere la differenza tra questo e let(:mailer_class) { AxeMailer }.

Chiedo questo perché attualmente quando eseguo il test, si lamenterà name è nullo. Ma se lo avessi cambiato, funzionerebbe bene.

Penso che questo problema sia iniziato dopo l'utilizzo di Rails 3.2 e penso che name sia ereditato da AbstractController :: Base.

Questo è lo stesso nella console (il che significa che non è specifico di Rspec), posso fare AxeMailer.name senza errori, ma se faccio Class.new(AxeMailer) c'è il problema.

Le mie domande sono:

  1. C'è una ragione per usare Class.new(AxeMailer) oltre AxeMailer
  2. C'è un problema se mi limito a cambiare questo?
  3. C'è un modo per non cambiare la specifica e farla passare?
+0

Puoi inserire più del codice di prova oltre al metodo 'let'? Questo ci aiuterebbe a determinare il motivo per cui è stato scritto in questo modo. –

+0

appena aggiunto, sarebbe sufficiente? – lulalala

+0

per me, non ci sono ragioni. – shingara

risposta

2

Suppongo che sia stato scritto questo a causa della linea mailer_class.username 'username'. Se hai usato direttamente AxeMailer, l'impostazione username verrebbe trasferita tra i test. Creando una nuova sottoclasse per ciascun test, è possibile assicurarsi che nessuno stato tra di essi venga trasferito.

+0

Penso che questo sia probabilmente il motivo (che comunque non è così importante). L'ho modificato in: '@controller_path || = parent.name.sub (/ Mailer $ /, '') .underscore' e sembra passare per ora – lulalala

0

Non so se mailer_class viene utilizzato all'interno della specifica reale o no, ma questo è quello che penso la configurazione dovrebbe essere simile:

let(:mailer) { AxeMailer.new } 

describe '#check' do 
    before do 
    AxeMailer.username 'username' 
    mailer.from '[email protected]' 
    mailer.subject 'subject' 
    end 
    subject { lambda { mailer.send(:check) } } 

Non solo non sembra essere un bisogno per la classe anonima che si stava creando. Inoltre, questa è solo la mia opinione, ma il tuo subject sembra un po 'strano. Le tue specifiche dovrebbero probabilmente avvolgere il soggetto in un lambda se necessario, ma non farlo nel tuo subject.

Per quanto riguarda l'errore che stavano vedendo in origine, le classi anonime non hanno nomi:

1.9.3-p0 :001 > Class.new.name 
=> nil 

Una parte di ActionMailer :: Base deve tentare di utilizzare il nome della classe di qualcosa (la registrazione forse) e si rompe quando è nulla.

+0

Grazie. Il 'nome' è usato nel metodo' self.controller_path'. Sovrascrive il 'self.controller_path' di' AbstractController :: Base'.Dal momento che sta iniziando una nuova versione di "AbstractController :: Base", dovrebbe funzionare anche (e ha funzionato in precedenza). – lulalala

Problemi correlati