2012-03-13 26 views
5

我正在閱讀某人離開公司的Rspec。我想知道這行:Class.new在這個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) } } 

它是測試這個類:

class AxeMailer < AbstractController::Base 

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

我想知道這一點,let(:mailer_class) { AxeMailer }之間的區別。

我問這個,因爲目前我運行測試的時候,會報錯name是零。但如果我改變它,它會測試罰款。

我覺得這個問題在使用Rails 3.2之後就開始了,我認爲name是從AbstractController :: Base繼承而來的。

這是在控制檯(意味着它不是Rspec特定的),我可以做AxeMailer.name沒有錯誤,但如果我做Class.new(AxeMailer)是存在的問題。

我的問題是:

  1. 有沒有理由使用Class.new(AxeMailer)超過AxeMailer
  2. 有沒有,如果我只是改變這個問題呢?
  3. 有沒有辦法改變規範並使其通過?
+0

除了'let'方法外,你能發佈更多的測試代碼嗎?這將有助於我們確定爲什麼這樣寫。 – 2012-03-13 10:14:19

+0

剛剛添加了一些,這是否足夠? – lulalala 2012-03-13 10:19:46

+0

給我,沒有理由。 – shingara 2012-03-13 10:25:13

回答

2

我猜這是寫這是因爲mailer_class.username 'username'線。如果您直接使用AxeMailer,則username設置將在測試之間結束。通過爲每個測試創建一個新的子類,可以確保它們之間沒有狀態。

+0

我認爲這可能是原因(反正這並不重要)。我將它修改爲:'@controller_path || = parent.name.sub(/ Mailer $ /,'').underscore',現在似乎通​​過 – lulalala 2012-03-19 09:39:34

0

我不知道是否被實際的規範與否內部使用mailer_class,但是這是我覺得你的設置應該是這樣的:

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) } } 

那裏只是似乎沒有被需要正在創建的匿名類。此外,這只是我的意見,但你的subject看起來有點奇怪。如果需要,你的規範應該把這個主題包裝在一個lambda中,但是不要在你的subject中這樣做。

關於你最初看到的錯誤,匿名類沒有名稱:

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

的ActionMailer :: Base的一些部分必須嘗試使用​​類名的東西(也許記錄),並休息時它是零。

+0

謝謝。 'name'用在'self.controller_path'方法中。它重寫'AbstractController :: Base'的'self.controller_path'。由於它正在創建一種'AbstractController :: Base',它也應該可以工作(並且以前一直在工作)。 – lulalala 2012-03-14 01:54:52