RSpec查看测试:如何修改参数?

seb*_*ger 11 rspec ruby-on-rails

我试图用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 %>
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

我想在RSpec中测试我的视图(没有控制器),但我无法将此参数输入到我的params变量中.我试过assign各种不同的口味:

  • assign[:params] = {:sort_by => 'name'}
  • assign[:params][:sort_by] = 'name'
  • ...

到目前为止没有成功.每个想法都表示赞赏.

fer*_*nyb 34

如果它是一个控制器测试,那么它将是

controller.stub!(:params).and_return {}
Run Code Online (Sandbox Code Playgroud)

如果它是一个辅助测试,那么它将是:

helper.stub!(:params).and_return {}
Run Code Online (Sandbox Code Playgroud)

它的视图测试将是:

view.stub!(:params).and_return {}
Run Code Online (Sandbox Code Playgroud)

如果您收到如下警告.

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)
Run Code Online (Sandbox Code Playgroud)

你可以改成它

allow(view).to receive(:params).and_return({sort_by: 'name'})
Run Code Online (Sandbox Code Playgroud)


Dam*_*IEU 11

那是因为你不应该params在你的观点中使用.
我认为使用帮助器的最好方法.

<div>Sorted by <%= sorted_by %></div>
Run Code Online (Sandbox Code Playgroud)

并在您的一个帮助文件中

def sorted_by
    params[:sorted_by].capitalize
end
Run Code Online (Sandbox Code Playgroud)

然后,您可以非常轻松地测试助手(因为在助手测试中,您可以定义params请求.


小智 5

简单的方法是这样做:

helper.params = {:foo => '1', :bar => '2'}
Run Code Online (Sandbox Code Playgroud)

但总的来说,最好是在可行的情况下进行更多集成,而不是"存根"值.所以我更喜欢使用integrate_views控制器测试.然后你可以指定get的params ,并测试整个流程的工作,从发送params到控制器,到控制器处理它们,最后到渲染.

我通常也喜欢将视图逻辑拉出到帮助器中,这可以更容易测试.

例如,假设我有一个叫帮手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
Run Code Online (Sandbox Code Playgroud)

如果此功能的某些部分中断,此集成测试将提醒我.但我也希望能有一些单元测试来帮助我查明破损情况.

我将首先让助手使用实例变量而不是直接访问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
Run Code Online (Sandbox Code Playgroud)

现在我也可以轻松执行辅助单元测试:

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
Run Code Online (Sandbox Code Playgroud)