2012-12-06 60 views
2

在Sinatra中工作時,本地對象request已創建並可供所有視圖和幫助程序使用。所以,我可以作出ApplicationHelper模塊的輔助方法,如果helper方法被稱爲視圖,他們可以反過來調用request對象,像這樣:Ruby:模擬本地對象以測試模塊方法

module ApplicationHelper 
    def nav_link_to(text,path) 
    path == request.path_info ? klass = 'class="current"' : klass = '' 
    %Q|<a href="#{path}" #{klass}>#{text}</a>| 
    end 
end 

現在,我想測試這一點,但在我的測試中request對象不存在。我試圖嘲笑它,但沒有奏效。這是我的測試到目前爲止:

require 'minitest_helper' 
require 'helpers/application_helper' 

describe ApplicationHelper do 

    before :all do 
    @helper = Object.new 
    @helper.extend(ApplicationHelper) 
    end 

    describe "nav links" do 
    before :each do 
     request = MiniTest::Mock.new 
     request.expect :path_info, '/' 
    end 

    it "should return a link to a path" do 
     @helper.nav_link_to('test','/test').must_equal '<a href="/test">test</a>' 
    end 

    it "should return an anchor link to the current path with class 'current'" do 
     @helper.nav_link_to('test','/').must_equal '<a href="test" class="current">test</a>' 
    end 
    end 
end 

那麼,你怎麼能嘲笑一個'本地'對象,以便你的測試可以調用它的代碼?

回答

2

您需要確保@helper對象上有一個返回模擬請求對象的request方法。

在RSpec中,我只是將它存根。我不是特別熟悉MINITEST,但咋一看認爲,這可能會在最新版本的工作(如果你在before :each改變request@request):

it "should return a link to a path" do 
    @helper.stub :request, @request do 
    @helper.nav_link_to('test','/test').must_equal '<a href="/test">test</a>' 
    end 
end 

更新

由於MINITEST要求在對象上已經定義了殘樁方法,則可以使@helperStruct.new(:request)的實例而不是Object,即

@helper = Struct.new(:request).new 

實際上,這樣做可能根本就不需要存根!你可以做

before :each do 
    @helper.request = MiniTest::Mock.new 
    @helper.request.expect :path_info, '/' 
end 
+0

這是有道理的,唯一的問題是MiniTest存根需要該方法已經存在,如果我通常在模塊上定義它,它會覆蓋實際應用中我想要的一個...所以,這幾乎讓我在那裏,現在我需要仔細研究一下 – Andrew

+0

啊,好的。你可以做'@helper = Struct.new(:request).new' –

+0

噢,這可能比我有更好的想法!我在想'@helper.instance_eval {def request;零;結束;}'...讓我看看你的方法真的很快 – Andrew