有没有办法在 RSpec 控制器测试中测试模板是否具有属性?

问题描述

所以我正在做我的第一个 Rails 项目,并且正在着手设置一些自动化测试。现在,我有一个带有 select 标签的表单模板,它根据模拟的 API 响应动态获取其信息。截至目前,我的模板已成功呈现,但我希望能够访问该 select 标记并查看其子 options 是否与我的模拟 API 响应匹配。无法在有关此特定用例的文档中找到很多内容,希望这里的某人能够指出我正确的方向。到目前为止,这基本上是我所拥有的:

RSpec.describe MyController,type: :controller,do
  describe "GET my_thing/index" do
    it "renders the index template" do
      stub_request(:get,"https://outsideapi.net/endpoint").
        to_return(status: 200,body: {
                    "values" => [
                      { "name": "foo","id": "10000" },{ "name": "bar","id": "10001" },{ "name": "baz","id": "10002" },],}.to_json,headers: {})

      get :index,params: { request_identifier: generate_request_identifier() }
      expect(response).to have_http_status(:success)
      expect(response).to render_template(:index)
      # Some code that will hopefully get elements off the template
    end
  end

解决方法

根据Rspec docs的控制器测试:

默认情况下,不渲染视图。请参阅默认情况下的视图和 render_views 以了解详细信息。

首先,您需要通过在测试套件中添加 render_views 指令作为 mentioned here 来指示 Rspec 呈现控制器视图:

require "rails_helper"

RSpec.describe WidgetsController,:type => :controller do
  render_views # <-- This

  describe "GET index" do
    it "has a widgets related heading" do
      get :index
      expect(response.body).to match /<h1>.*widgets/im
    end
  end
end

最后,您将能够使用类似这样的东西将 JSON 数组与呈现的 HTML 匹配(代码未经测试,但它有望推动这一点):


RSpec.describe MyController,type: :controller,do
  describe "GET my_thing/index" do
    it "renders the index template" do
      # Can also be added below the `describe` call if view rendering is needed elsewhere.
      render_views
      select_values = [
                      { "name": "foo","id": "10000" },{ "name": "bar","id": "10001" },{ "name": "baz","id": "10002" },]
      stub_request(:get,"https://outsideapi.net/endpoint").
        to_return(status: 200,body: {
                    "values" => select_values,}.to_json,headers: {})

      get :index,params: { request_identifier: generate_request_identifier() }
      expect(response).to have_http_status(:success)
      expect(response).to render_template(:index)
      # Extract the select value names as an array of strings.
      select_value_names = select_values.map {|v| v['name']}
      expect(response.body).to include(select_value_names)
    end
  end

另外,如果您正在针对页面内容运行测试,您可能需要考虑使用验收测试框架,例如 Capybara,它与 Rspec 集成良好。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...