我正在尝试用RSpec测试我的观点。导致我麻烦的特定视图会根据url参数更改其外观:
link_to "sort>name", model_path(:sort_by => 'name')
会产生http://mydomain/model?sort_by=name
我的视图然后使用这个参数:
<% if params[:sort_by] == 'name' %>
<div>Sorted by Name</div>
<% end %>
RSpec看起来像这样:
it "should tell the user the attribute for sorting order" do
#Problem: assign params[:sort_for] = 'name'
render "/groups/index.html.erb"
response.should have_tag("div", "Sorted by Name")
end
我想在RSpec中测试我的视图(没有控制器),但我无法将此参数放入我的params
变量中。我尝试了各种不同的assign
:
assign[:params] = {:sort_by => 'name'}
assign[:params][:sort_by] = 'name'
答案 0 :(得分:34)
如果是控制器测试那么它将是
controller.stub!(:params).and_return {}
如果它是辅助测试,那么它将是:
helper.stub!(:params).and_return {}
它的视图测试将是:
view.stub!(:params).and_return {}
如果你收到如下警告。
Deprecation Warnings:
Using `stub` from rspec-mocks' old `:should` syntax without explicitly enabling the syntax is deprecated. Use the new `:expect` syntax or explicitly enable `:should` instead. Called from /home/akbarbin/Documents/Office/projects/portfolio/spec/views/admin/waste_places/new.html.erb_spec.rb:7:in `block (2 levels) in <top (required)>'.
If you need more of the backtrace for any of these deprecations to
identify where to make the necessary changes, you can configure
`config.raise_errors_for_deprecations!`, and it will turn the
deprecation warnings into errors, giving you the full backtrace.
1 deprecation warning total
Finished in 4.86 seconds (files took 4.72 seconds to load)
您可以将其更改为
allow(view).to receive(:params).and_return({sort_by: 'name'})
答案 1 :(得分:11)
那是因为你不应该在你的观点中使用params
我认为使用助手的最佳方式。
<div>Sorted by <%= sorted_by %></div>
在你的一个帮助文件中
def sorted_by
params[:sorted_by].capitalize
end
然后,您可以非常轻松地测试助手(因为在助手测试中,您可以定义params
请求。
答案 2 :(得分:5)
简单的方法就是这样做:
helper.params = {:foo => '1', :bar => '2'}
但总的来说,在可行的情况下,更好的是整合y而不是“存根”值。所以我更喜欢使用 integrate_views 的控制器测试。然后你可以指定 get 的参数,并测试整个流程的工作原理,从发送参数到控制器,到控制器处理它们,最后再渲染。
我通常也倾向于将视图逻辑拉出到帮助器中,这样可以更容易测试。
例如,假设我有一个名为 selection_list 的帮助器,它返回一个Hash,其“selected_preset”键依赖于 params [:selected_preset] ,默认为42,如果为参数指定了一个空值。
这是一个控制器测试,我们称之为 integrate_views (如果您正在进行实际视图测试,当然可以做同样的事情。)
describe '#show' do
describe 'selected_preset' do
it 'should default to 42 if no value was entered' do
get :show, :params => {:selected_preset => ''}
response.template.selection_list[:selected_preset].should == 42
如果此功能的某些部分中断,此集成测试将提醒我。但我也希望有一些单元测试来帮助我精确定位破坏。
我首先让帮助者使用实例变量而不是直接访问params。我将通过在get下面直接添加一行来更改上面的代码,如下所示:
describe '#show' do
describe 'selected_preset' do
it 'should default to 42 if no value was entered' do
get :show, :params => {:selected_preset => ''}
assigns[:selected_preset].should == 42 # check instance variable is set
response.template.selection_list[:selected_preset].should == 42
现在我也可以轻松执行辅助单元测试:
describe MyHelper do
describe '#selection_list' do
it 'should include the selected preset' do
assigns[:selected_preset] = 3
helper.selection_list[:selected_preset].should == 3
答案 3 :(得分:2)
另一种设置视图参数的方法:
controller.request.path_parameters[:some_param] = 'a value'