【发布时间】:2016-08-30 08:16:00
【问题描述】:
我要做的就是测试控制器是否真的在调用render。
注意:
我不关心这个测试的输出,所以我不想检查response.body或assert_template等。我只想确保render的方法被发送到控制器。
控制器动作:
def create
render json: { error: "some error" }, status: :unprocessable_entity
end
规格:
剔除授权回调:
before do
allow(AuthenticateRequest).to receive(:call).and_return(true)
allow_any_instance_of(CanCan::ControllerResource).to receive(:load_resource).and_return(nil)
end
这实际上是规范的唯一期望,因此没有任何冲突。 它“在json中呈现错误”做 参数 = { json:{错误:“一些错误”}, 状态: :unprocessable_entity }
expect(controller).to receive(:render).with(args)
post :create, user: { upload: upload }
end
# rspec spec/controllers
# FAILURE:
expected: ({:json=>{:error=>"some error"}, :status=>:unprocessable_entity})
got: (no args)
这是我做错事的可能线索。这就是我删除参数期望时发生的情况:
it "renders error in json" do
expect(controller).to receive(:render) # no args expectation
post :create, user: { upload: upload } # called two times??
end
# rspec spec/controllers
# FAILURE:
expected: 1 time with any arguments
received: 2 times with any arguments
我在这里错过了什么?
更新:
这是另一个尝试。又一个错误:
it "renders error in json" do
expect(controller).to receive(:render).with(
foo: { error: "some error" },
status: :unprocessable_entity
).at_least(:once)
post :create, price_patch_upload: { upload: "upload" }, format: :json
end
...但是当我更改测试以匹配预期时。注意at_least(:once) 的期望。即使控制器渲染两次,你也会认为这会通过:
it "renders error in json" do
expect(controller).to receive(:render).with(
json: { error: "some error" },
status: :unprocessable_entity
).at_least(:once)
post :create, price_patch_upload: { upload: "upload" }, format: :json
end
???
【问题讨论】:
-
您的控制器或
ApplicationController中是否有可能呈现两次的before_action?或者,如果您“隐藏”了before_action,比如可以验证或授权的宝石之类的? -
啊,是的,好点。是的,我愿意。应用程序控制器调用
authenticate_request,用户控制器有CanCan 的load_and_authorize_resource。不过,我想我已经排除了这些方法。我会更新问题以供参考。 -
我刚刚重现了与您相同的问题。我目前的猜测是它会渲染两次,因为在引擎盖下 rails 仍然会调用
render(即使我认为在已经手动调用render时它不会再这样做了)。到目前为止,我所有的尝试都没有奏效。目前唯一的快速解决方案是expect(response.body).to eq {error: 'some error'}和expect(response).to have_http_status(:unprocessable_entity)和expect(response.content_type).to eq 'application/json'
标签: ruby-on-rails unit-testing rspec