Rspec 请求规范检查响应正文

the*_*ter 3 rspec ruby-on-rails rspec-rails ruby-on-rails-3

由于 rspec 3.5 请求规范用于测试控制器行为以及路由测试以及视图与内容的正确呈现。最后一部分让我有点烦恼,因为我不明白视图规范中的内容与请求规范中的内容之间的细线。

relishapp 上,我发现了这篇文章:

expect(response.body).to include("Widget was successfully created.")

这诱使我在请求测试中包含以下内容:

describe "Index page" do
  ....
  it 'includes a link to cars_parts' do
    get "/car_overview"      
    expect(response.body).to include("car_parts_path")
  end
  ....
end 
Run Code Online (Sandbox Code Playgroud)

此测试失败。在视图我使用link_tocar_parts url_helper。失败的测试转储了整个 response.body 字符串,我看到了car_parts_path但 rspec 没有看到它。我如何更改我的测试以使其在不使用水豚的情况下通过,因为它现在只能用于功能规格。我到底做对了还是应该在其他地方进行这种测试?

Joh*_*her 8

我认为您可能需要将字符串更改为方法。

expect(response.body).to include("car_parts_path")
Run Code Online (Sandbox Code Playgroud)

expect(response.body).to include(car_parts_path) # Remove the quotes
Run Code Online (Sandbox Code Playgroud)

解释

car_parts_path是 Rails 中的一种方法,它将评估为实际路径。如果您在视图中使用该 URL 助手,这应该可以工作。

但我认为响应体是一个字符串?

是的,是的。当您调用 时car_parts_path,您正在调用 Rails 框架中的 Ruby 方法。

car_parts_path返回一个字符串。该字符串将为"/car_parts".

基本上,任何时候你看到car_parts_path,都可以把它想象"/car_parts"成一个字符串。因为两者完全等价。

在测试中

因此,当您在测试中遇到此问题时:

expect(response.body).to include(car_parts_path) # car_parts_path is a method that returns "/car_parts" so it's the same as...
Run Code Online (Sandbox Code Playgroud)

它的评估结果与:

expect(response.body).to include("/car_parts")
Run Code Online (Sandbox Code Playgroud)

在视图中

在您的 ERB 视图中,您将拥有:

expect(response.body).to include(car_parts_path) # car_parts_path is a method that returns "/car_parts" so it's the same as...
Run Code Online (Sandbox Code Playgroud)

这被评估为:

expect(response.body).to include("/car_parts")
Run Code Online (Sandbox Code Playgroud)

这会a在您的 html 中呈现一个标签:

<a href="/car_parts">Car Parts</a>
Run Code Online (Sandbox Code Playgroud)

结论

您正在检查"/car_parts"响应正文,并且视图包含该字符串,现在测试通过了,一切就绪!

为什么我的原始代码不起作用?

Rails 正在寻找"car_parts_path"一个字符串 - 而视图在任何地方都不包含它。

您正在寻找作为字符串的方法名称,而不是方法返回的字符串。

还有什么问题,尽管问!