我遇到以下问题:
环境:Ruby:2.3.1和Rails 5.0.0.1
我正在尝试使用RSpec和Factory Girl验证日期时间字段。
我收到了这个错误:
expected: "2016-11-11 13:30:31 UTC" (From Factory Girl)
got: "2016-11-11T13:30:31.218Z" (From database)
我的代码:
klass_object = FactoryGirl.create(:character)
klass = Character
RSpec.shared_examples 'API GET #index' do |klass|
before { get :index, params: params, accept: Mime[:json] }
it "returns a list of #{klass.to_s.underscore.pluralize}" do
object_array = json(response.body)
klass_attributes = klass.attribute_names.without("id", "created_at", "updated_at").map(&:to_sym)
klass_attributes.each do |attribute|
object_array.each do |object|
expect(object[attribute].to_s).to eq(klass_object[attribute].to_s)
end
end
end
...
end
厂:
FactoryGirl.define do
factory :character do
marvel_id { Faker::Number.number(6).to_i }
name { Faker::Superhero.name }
description { Faker::Hipster.paragraphs(1) }
modified { Faker::Date.between(DateTime.now - 1, DateTime.now) }
factory :invalid_character do
id ''
name ''
marvel_id ''
modified ''
end
end
端
如何更正此问题?
我做到了,它有效,但我认为它不太好。还有更好的方法吗?
object_array.each do |object|
if ActiveSupport::TimeWithZone == klass_object[attribute].class
expect(object[attribute].to_datetime.strftime("%Y-%m-%d %H:%M:%S")).to eq(klass_object[attribute].to_datetime.strftime("%Y-%m-%d %H:%M:%S"))
else
expect(object[attribute].to_s).to eq(klass_object[attribute].to_s)
end
end
感谢您的帮助。
答案 0 :(得分:2)
我建议你改变比较结果的方法。您可以使用基于黄金大师的想法的方法。
根据此方法,您可以拍摄对象的快照,然后将对象的所有未来版本与快照进行比较。
在你的情况下,你可以第一次写json fixture,检查json是否正确,并在下次将它与结果json进行比较。
例如
<强> approved.json 强>
[
{
"travel_time_seconds": 43200,
"available_seats_amount": 10,
"departure_at": "2016-04-08T02:00:00.000+03:00",
"arrival_at": "2016-04-08T17:00:00.000+03:00",
"source_point_name": "New York",
"destination_point_name": "Moscow",
"tickets_count": 2
}
]
<强> controller_spec.rb 强>
RSpec.shared_examples 'API GET #index' do |klass|
before { get :index, params: params, accept: Mime[:json] }
it "returns a list of #{klass.to_s.underscore.pluralize}" do
verify(format: :json) { json(response.body).map {|o| o.except('id', 'created_at', 'updated_at' }
end
...
end
例如,approvals gem可以为您提供帮助
答案 1 :(得分:1)
我知道这是一个非常古老的问题,但我今天刚刚遇到了这个问题的解决方案而无法找到另一个答案。我也一直在使用Faker,但是日期/时间格式在Ruby时间数学上似乎没有很好的效果,而且没有大量的探索。
但是,如果您在工厂中使用Time
,然后将其转换为.to_i
,它将以正确的格式发送到数据库,以便在rspec中进行比较。
迁移:
class CreateExperiences < ActiveRecord::Migration[5.2]
def change
create_table :experiences do |t|
t.datetime :start_date
厂:
FactoryBot.define do
when_it_started = Time.zone.now - rand(3000).days
factory :experience do
start_date { when_it_started.to_i }
规格:
RSpec.describe "Experiences API", type: :request do
let!(:valid_attributes) { attributes_for(:experience) }
describe "POST /v1/experiences" do
before { post "/v1/experiences", params: valid_attributes }
it "creates an experience" do
expect(JSON.parse(response.body).except("id", "created_at", "updated_at")).to eq(valid_attributes.stringify_keys)
end
然后我的测试通过了。希望这会帮助别人!
答案 2 :(得分:0)
尝试使用to_datetime
代替to_s
expect(object[attribute].to_datetime).to eq(klass_object[attribute].to_datetime)