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
我的问题是我的 Spec 总是 通过 (!),即使我在 index.csv.erb
文件中放了一堆废话。 RSpec.
似乎甚至没有评估/测试视图文件
这怎么可能?我在这里错过了什么?
格式选项应在参数之外指定,即 get :index, params: {}, format: :csv}
.
关于 RSpec 评估视图,不,在控制器测试中,无论格式如何,它都不会。但是,可以使用 RSpec 测试视图:https://relishapp.com/rspec/rspec-rails/v/2-0/docs/view-specs/view-spec
控制器 tests/specs 是这些奇怪的存根创作,源于孤立的单元测试控制器的想法。这个想法被证明是有缺陷的,最近真的不流行了。
控制器规范实际上不会向通过路由的应用程序发出真正的 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
但更好、更适合未来的选择是使用 request spec。
The official recommendation of the Rails team and the RSpec core team
is to write request specs instead. Request specs allow you to focus on
a single controller action, but unlike controller tests involve the
router, the middleware stack, and both rack requests and responses.
This adds realism to the test that you are writing, and helps avoid
many of the issues that are common in controller specs.
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
在我的 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
我的问题是我的 Spec 总是 通过 (!),即使我在 index.csv.erb
文件中放了一堆废话。 RSpec.
这怎么可能?我在这里错过了什么?
格式选项应在参数之外指定,即
get :index, params: {}, format: :csv}
.关于 RSpec 评估视图,不,在控制器测试中,无论格式如何,它都不会。但是,可以使用 RSpec 测试视图:https://relishapp.com/rspec/rspec-rails/v/2-0/docs/view-specs/view-spec
控制器 tests/specs 是这些奇怪的存根创作,源于孤立的单元测试控制器的想法。这个想法被证明是有缺陷的,最近真的不流行了。
控制器规范实际上不会向通过路由的应用程序发出真正的 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
但更好、更适合未来的选择是使用 request spec。
The official recommendation of the Rails team and the RSpec core team is to write request specs instead. Request specs allow you to focus on a single controller action, but unlike controller tests involve the router, the middleware stack, and both rack requests and responses. This adds realism to the test that you are writing, and helps avoid many of the issues that are common in controller specs. 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