2012-11-20 33 views
4

我認爲我的寶石測試用於運行的虛擬應用程序設置不正確,因爲當我在Gadget實例(來自虛擬應用程序的存根模型)上調用url_for時,創業板的助手裏,我得到寶石測試無法找到使用url_for的路線

undefined method `gadgets_path' for #<#<Class:0x007fe274bc1228>:0x007fe273d45eb0> 

背景:我分叉寶石並提出了一些顯著的變化。 (Here's the fork。)現在我試圖使rspec測試工作,以便我可以驗證我的更新。

測試設置爲像Rails引擎,在spec目錄中有一個虛擬應用程序。該應用程序有一個適當的控制器的一個模型(Gadget)和spec/dummy/environment/routes.rb文件中聲明的資源:

Dummy::Application.routes.draw do 
    resources :gadgets 
end 

spec/spec_helper.rb文件看起來是這樣的:

ENV["RAILS_ENV"] ||= "test" 

require File.expand_path("../dummy/config/environment", __FILE__) 
require 'rspec/rails' 

require 'rspec/autorun' 

RSpec.configure do |config| 
    config.mock_framework = :rspec 
    config.fixture_path = "#{::Rails.root}/spec/fixtures" 
    config.use_transactional_fixtures = true 
    config.infer_base_class_for_anonymous_controllers = false 
    config.order = "random" 

    config.include Rails.application.routes.url_helpers 
end 

(實際上,你可以看到完整的測試在the project's github repo設置。我實際上打開an issue這一個星期前,但只有現在我四處尋求解決它。)

這是一個測試是不等待創建一個Gadget實例,然後以此作爲參數調用幫助器。當助手嘗試url_for(@gadget)時,會觸發上述錯誤。

這裏有什麼問題?

ETA Dec 04:更新爲當前的spec_helper.rb

回答

9

更新

把這個你spec_helper.rb內 - 至少在這個工作對我來說(我克隆你的回購)

ActionView::TestCase::TestController.instance_eval do 
    helper Rails.application.routes.url_helpers#, (append other helpers you need) 
end 
ActionView::TestCase::TestController.class_eval do 
    def _routes 
    Rails.application.routes 
    end 
end 

真正的問題是,TestControllerActionController::Base之前的子類ActionController::Base用路由幫助器方法進行了擴展。
所以你需要將它注入TestController。此外,AbstractController :: UrlFor需要執行_routes


爲了使用路由傭工你應該插入

Rspec.configure do |config| 
    config.include Rails.application.routes.url_helpers 
    ... 
end 
在spec_helper.rb這使得所有 something_path方法可用

。 周圍的真實問題另一種方式將存根出來的幫手,像這樣:

helper.stub!(:url_for).and_return("/path") 
+0

這看起來很有希望,當我進入虛擬應用程序並使用Rails控制檯時,我可以戳出該對象並獲取路徑。但是,它不允許測試運行。我已經用你的建議更新了上面的'spec_helper.rb'代碼。 (它也在Github上更新。) – pjmorse

+0

我更新了答案以反映我的最新努力 – krichard

+0

您對「真正的問題」絕對正確,而且它本身解決了問題。 – pjmorse

1

雖然這是相當多的源代碼接受,在我看來,你打電話editable_field,而這又調用url_for。但是url_for只能在控制器的環境下工作,而您只是在規範中調用它。

因此,或許將這種方法剔除或進行集成測試將是一個合適的解決方法。

+0

'editable_field'是一個輔助方法。實際上,'url_for'確實在輔助器中工作得很好;它在測試環境中不起作用。 stubbing'editable_field'不是一種合適的解決方法,因爲它是我試圖測試的方法。 – pjmorse

+0

如果你拉起軌道控制檯,並執行'editable_field'它會工作嗎?我不認爲它會,因爲它需要在一個請求的上下文中,它建立了'url_for'的工作環境。所以我建議存根'url_for'而不是'editable_field'。 –

+0

你是對的,它在控制檯中不起作用。現在,這三個選票用於存留'url_for',這很有道理。 – pjmorse