2012-05-07 51 views
1

聲明:我對RSpec和TDD一般都很陌生,所以我可能會完全用錯誤的方式解決這個問題。在函數中初始化的對象上的RSpec any_instance stubbing

我想寫一個命令行界面給我的程序,它接受一個命令並生成一個類來處理它。程序打算工作的方式類似於git和svn等工具;即你可以傳遞「srs init」來初始化程序,「srs add」添加一些東西,等等。

所以我有一個類需要ARGV並將其關閉,以一個特定的處理程序,它看起來是這樣的:

class CLI 
    def run!(*arguments) 
     command = arguments.shift 
     case command 
     when "init" 
      CLI::Init.new.run!(*arguments) 
     end 
    end 
end 

我的初始化處理程序則是這樣的:

class CLI 
    class Init 
     def initialize() 
     end 
     def run!(*arguments) 
     end 
    end 
end 

我我正在爲CLI類的路由功能編寫一個測試套件。如果我使用下面的RSpec的失敗:

describe CLI do 
    it "should launch the Init handler if we pass init" do 
     CLI::Init.any_instance.should_receive(:run!) 
     CLI::run!(*["init"]) 
    end 
end 

不過,如果我更換呼叫CLI::run!與直接調用初始化處理程序的運行通過; i.e.:-

describe CLI do 
    it "should launch the Init handler if we pass init" do 
     CLI::Init.any_instance.should_receive(:run!) 
     CLI::Init.new.run!(*[]) 
    end 
end 

看起來好像any_instance僅適用於定義/在describe塊內構造的情況下,但我真的不知道。如果任何人都可以爲我提供任何指導,或者我可以檢查在我的run!函數中構造的實例上調用了類方法,還是首先測試此功能的更好方法,我會非常感激。

+0

它是如何失敗?你可以顯示痕跡嗎?乍一看你的代碼看起來很好。 – x1a4

+1

@ x1a4,在閱讀你的評論後又看了一遍,你是對的!我簡化了這篇文章的代碼,簡化的代碼工作正常。應該在發佈之前以相同的方式測試它失敗。將提出一個答案,解釋一旦我的八小時限制過期,問題是什麼。 – danielpwright

回答

0

有時解釋問題揭示了答案。事實上,在處理程序的名稱,「初始化」正在作爲參數傳遞給describe塊,更是這樣的:

%w{Init}.each do |cmd| 
    describe CLI do 
     it "should launch the #{cmd} handler if we pass #{cmd}" do 
      CLI.const_get(cmd).any_instance.should_receive(:run!) 
      CLI::run!(*[cmd]) 
     end 
    end 
end 

在描述我拿出循環,以簡化問題的問題,但在這樣做的過程中發生了一個重要的變化 - 類名Init,以大寫字母「I」開始,而傳遞給命令行init的命令名以小「i」開頭。

所以原來測試失敗了,因爲我試圖通過命令「初始化」時,我應該已經傳遞命令「初始化」。

TL; DR - 原始碼確實實際工作!對不起,麻煩了。