我正在为rails视图编写测试,假设视图类似于:
show.json.rep
r.element :user, @user do |u|
r.element :id, u.id
r.element :somefield1, u.somefield1
// a lot of fields here
r.element :somefield100, u.somefield100
end
现在我想测试它生成的json,并且只关注id
字段。
如果我的测试代码写得像:
describe "show.json.rep" do
it "will generate json with correct id" do
assign(:user, mock(:user, :id=>111))
render
puts "######### generate json:"
puts rendered
...
end
end
它会报告这样的错误:
Failure/Error: render
ActionView::Template::Error:
Mock :user received unexpected message :somefield1 with (no args)
我不想模仿我感兴趣的所有字段somefieldX
,所以我尝试了as_null_object
:
describe "show.json.rep" do
it "will generate json with correct id" do
assign(:user, mock(:user, :id=>111).as_null_object)
render
puts "######### generate json:"
puts rendered
...
end
end
这一次,它没有报告该错误,但奇怪的是,rendered
值为null
!!
######### generate json:
null
我不确定为什么以及如何修复它?或者还有其他方法可以让我提供我感兴趣的领域吗?
答案 0 :(得分:0)
在创建对象时设置id
,然后调用as_null_object将导致id(和任何其他方法)返回nil。
使用as_null_object方法忽略任何不是的消息 明确地设置为存根或消息期望。
这就是你如何存根id
方法:
require 'json'
describe "show.json.rep" do
let(:user) { double("User").as_null_object }
let(:json) { JSON.parse(rendered).symbolize_keys! }
before(:each) do
allow(user).to receive(:id).and_return(666)
assign(:user, user)
render
end
it "will generate json with correct id" do
expect(json[:id]).to equal (user.id)
end
end
但从长远来看,你可能应该使用fixtures或factories,而不是在整个测试中设置双打。 我也更喜欢使用ActiveModel serializers,因为它们更容易,更快速,因为你没有编码和解析JSON。
修改强>
另一种解决方案是使用User.new
let(:user) { User.new(id: 666) }