繁体   English   中英

Rspec在测试XML或CSV输出时神秘地通过了

[英]Rspec mysteriously passes when testing XML or CSV output

在我的Rails 5应用程序中,我有以下内容:

class InvoicesController < ApplicationController

  def index
    @invoices = current_account.invoices
    respond_to do |format|
      format.csv do
        invoices_file(:csv)
      end
      format.xml do
        invoices_file(:xml)
      end
    end
  end

private

  def invoices_file(type)
    headers['Content-Disposition'] = "inline; filename=\"invoices.#{type.to_s}\""
  end

end

describe InvoicesController, :type => :controller do

  it "renders a csv attachment" do
    get :index, :params => {:format => :csv}
    expect(response.headers["Content-Type"]).to eq("text/csv; charset=utf-8")
    expect(response).to have_http_status(200)
    expect(response).to render_template :index
  end

end

我的问题是,即使我在index.csv.erb文件中放了一堆废话,我的Spec总是通过 (!)。 似乎该视图文件甚至没有被RSpec评估/测试。

这怎么可能? 我在这里想念什么?

  1. 格式选项应在参数之外指定,即get :index, params: {}, format: :csv}

  2. 关于RSpec评估视图,不对,在控制器测试中,不考虑其格式。 但是,可以使用RSpec测试视图: https : //relishapp.com/rspec/rspec-rails/v/2-0/docs/view-specs/view-spec

控制器测试/规范是这些怪异的创意,它们是孤立地进行单元测试控制器的想法而产生的。 这个想法被证明是非常有缺陷的,并且最近真的不流行了。

控制器规范实际上并不向通过路由的应用程序发出真正的HTTP请求。 相反,他们只是伪造它并通过一个伪造的请求。

为了使测试更快,它们也不会真正渲染视图。 这就是为什么它不会像您期望的那样出错的原因。 而且响应也不是真正的机架响应对象。

您可以使RSpec使用render_views呈现视图。

describe InvoicesController, :type => :controller do
  render_views
  it "renders a csv attachment" do
    get :index, format: :csv
    expect(response.headers["Content-Type"]).to eq("text/csv; charset=utf-8")
    expect(response).to have_http_status(200)
    expect(response).to render_template :index
  end
end

但是更好的和更可靠的选择是使用请求规范

Rails团队和RSpec核心团队的官方建议是编写请求规范。 请求规范使您可以专注于单个控制器操作,但是与控制器测试不同,它涉及路由器,中间件堆栈以及机架的请求和响应。 这为您正在编写的测试增加了真实感,并有助于避免控制器规范中常见的许多问题。 http://rspec.info/blog/2016/07/rspec-3-5-has-been-released/

# spec/requests/invoices
require 'rails_helper'
require 'csv'
RSpec.describe "Invoices", type: :request do
  let(:csv) { response.body.parse_csv }
  # Group by the route
  describe "GET /invoices" do
    it "renders a csv attachment" do
      get invoices_path, format: :csv
      expect(response.headers["Content-Type"]).to eq("text/csv; charset=utf-8")
      expect(response).to have_http_status(200)
      expect(csv).to eq ["foo", "bar"] # just an example
    end
  end
end

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM