我正在为我的一个活动模型序列化器编写一个测试,以确保JSON输出是我所期望的。然而,我不明白为什么RSpec解析我的'expected'输出而忽略了我的testjob数组,我不明白为什么我不能让'expected'和'got'输出彼此相等。有一次,我甚至将'got'结果复制粘贴到我的'expected'输入,仍然收到一条失败消息,表明两个字符串不相等。然而,当我在REPL中使用**==比较这两个字符串时,输出是true**。我该如何解决这些问题以获得有效的测试?
RSpec Error:
Failures:
1) TestrunSerializer creates special JSON for the API
Failure/Error: expect(serializer.to_json).to eq('{"testrun":{"id":1,"run_at":null,"started_at":null,"state":"pending","completed_at":null,"testjobs":[{"id":2,"active":false,"testchunk_id":2,"testrun_id":1,"testchunk_name":"flair","testchunk":{"id":15,"name":"flair"}}],"branch":{"id":1,"name":"dev","repository":{"id":321,"url":"fakeurl.com"}}}}')
expected: "{\"testrun\":{\"id\":1,\"run_at\":null,\"started_at\":null,\"state\":\"pending\",\"completed_at\":nu...r\"}}],\"branch\":{\"id\":1,\"name\":\"dev\",\"repository\":{\"id\":321,\"url\":\"fakeurl.com\"}}}}"
got: "{\"testrun\":{\"id\":1,\"run_at\":null,\"started_at\":null,\"state\":\"pending\",\"completed_at\":nu...s\":[],\"branch\":{\"id\":1,\"name\":\"dev\",\"repository\":{\"id\":321,\"url\":\"fakeurl.com\"}}}}"
(compared using ==)
# ./spec/serializers/testrun_spec.rb:11:in `block (2 levels) in <top (required)>'
Finished in 0.79448 seconds (files took 5.63 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/serializers/testrun_spec.rb:8 # TestrunSerializer creates special JSON for the API
字符串
下面是RSpec测试:
require 'rails_helper'
describe TestrunSerializer, type: :serializer do
let(:repo) { Repository.create(id: 321, url: "fakeurl.com") }
let(:branch) { Branch.create(id: 1,name: "dev", repository_id: repo.id) }
let(:testchunk) { Testchunk.create(id: 15, name: "flair") }
it "creates special JSON for the API" do
serializer = TestrunSerializer.new Testrun.new("id":1, name: "name", "run_at": nil, state: "pending", branch_id: branch.id)
testjob = Testjob.create(id: 8, active: false, testchunk_id: testchunk.id, testrun_id: 1)
expect(serializer.to_json).to eq('{"testrun":{"id":1,"run_at":null,"started_at":null,"state":"pending","completed_at":null,"testjobs":[{"id":2,"active":false,"testchunk_id":2,"testrun_id":1,"testchunk_name":"flair","testchunk":{"id":15,"name":"flair"}}],"branch":{"id":1,"name":"dev","repository":{"id":321,"url":"fakeurl.com"}}}}')
end
end
型
下面是实际的序列化器:
class TestrunSerializer < ActiveModel::Serializer
attributes :id, :run_at, :started_at, :state, :completed_at, :testjobs
has_many :testjobs
has_one :branch
end
型
使用的技术:Rails 5.1、RSpec 3.6、Ruby 2.4
4条答案
按热度按时间gpfsuwkq1#
您的
testjobs
似乎不匹配字符串
vs
型
您应该设置您的规格,以便也返回
testjobs
。请注意,中间的diff字符串是
cut
--这是eq matcher与字符串一起使用时最烦人的部分之一。编辑:你可能习惯于切换到比较数组/哈希而不是字符串来获得更好的差异。
expect(serializer).to eq {testrun: "..."}
(在Assert中删除to_json
)drnojrws2#
这不会回答你的问题,但会让你回答你的问题。将其添加到
spec_helper.rb
,结果将不再被中心截断,因此中间没有神秘的块丢失。字符串
如果你不想看到兆字节长的消息,你也可以使用像
1000
或5000
这样的int来代替nil
(无限长度)。62o28rlo3#
您的测试没有通过的原因是微不足道的:在
it
块中,您在创建Testjob
记录时分配了Testrun id (1)
,但Testrun
记录不存在。SomeActiveRecord.new()
不会创建任何实际的记录,直到您在其上调用save()
,或者您可以为此调用SomeActiveRecord.create
。字符串
因此,最终的解决方案可能看起来像这样:
型
改进范围:
请查看
active_model_serializers
存储库中的:json
适配器测试:https://github.com/rails-api/active_model_serializers/blob/v0.10.6/test/action_controller/json/include_test.rb的数据。您可以使用
rspec
轻松地将测试转换为套件。如果你想测试json输出,那么你应该把测试放在
controller
或request
规范下;而不是在序列化器中。因为呈现JSON是适配器的责任;序列化程序只向适配器提供其中定义的所有属性和关联。zqry0prt4#
工作溶液:我添加了
serializer.testjobs << testjob
行来显式地将testjob与对象关联起来,现在测试通过了。