【发布时间】:2020-04-20 17:04:48
【问题描述】:
我正在尝试在我们公司的 Rails 应用程序中实施更多测试,并使用 Rspec、FactoryBot 和 Shoulda 匹配器来提供帮助。基础很容易实现,例如关联和存在_of。鉴于 FactoryBot 正在生成用于测试的良好实例,这是我遇到麻烦并遇到我不太了解如何解决的错误的更“异国情调”的问题。这是我正在测试的模型:
class Outage < ApplicationRecord
belongs_to :service
validates_presence_of :start_time, :end_time, :reason, :frequency
validates_numericality_of :start_time
validates_numericality_of :end_time, :is_greater_than => :start_time
end
这是 FactoryBot 文件:
FactoryBot.define do
factory :outage_fo, class: 'Outage' do
start_time { Time.now }
end_time { Time.now + Random.rand(1e5..1e6).floor}
is_recurring { false }
frequency { "None" }
reason { Faker::Company.bs }
service_id { Random.rand(1..50) }
end
factory :outage_ro, class: 'Outage' do
start_time { Time.now }
end_time { Time.now + Random.rand(1e5..1e6).floor}
is_recurring { true }
frequency { ["Daily", "Monthly" ].sample }
reason { Faker::Company.bs }
service_id { Random.rand(1..50) }
end
end
这是实际的 RSpec 测试:
require 'rails_helper'
RSpec.describe Outage, type: :model do
let(:outage_fo) { build(:outage_fo) }
describe "associations" do
it { should belong_to(:service) }
end
describe "validations" do
it { should validate_presence_of(:start_time) }
it { should validate_presence_of(:end_time) }
it { should validate_presence_of(:reason) }
it { should validate_presence_of(:frequency) }
it { should validate_numericality_of(:end_time).is_greater_than(Time.now) }
end
end
我得到的错误是:
1) Outage validations is expected to validate that :end_time looks like a number greater than 2020-04-20 12:57:33 -0400
Failure/Error: it { should validate_numericality_of(:end_time).is_greater_than(Time.now) }
Expected Outage to validate that :end_time looks like a number greater
than 2020-04-20 12:57:33 -0400, but this could not be proved.
After setting :end_time to ‹"2020-04-20 12:57:33 -0400"› -- which was
read back as ‹Mon, 20 Apr 2020 16:57:33 UTC +00:00› -- the matcher
expected the Outage to be invalid and to produce the validation error
"must be greater than 2020-04-20 12:57:33 -0400" on :end_time. The
record was indeed invalid, but it produced these validation errors
instead:
* service: ["must exist"]
* start_time: ["can't be blank"]
* reason: ["can't be blank"]
* end_time: ["is not a number"]
As indicated in the message above, :end_time seems to be changing
certain values as they are set, and this could have something to do
with why this test is failing. If you've overridden the writer method
for this attribute, then you may need to change it to make this test
pass, or do something else entirely.
# ./spec/models/outage_spec.rb:16:in `block (3 levels) in <top (required)>'
Finished in 0.24732 seconds (files took 1.87 seconds to load)
6 examples, 1 failure
Failed examples:
rspec ./spec/models/outage_spec.rb:16 # Outage validations is expected to validate that :end_time looks like a number greater than 2020-04-20 12:57:33 -0400
[12:57:33] (develop_2) tml_dashboard_2
// ♥ rspec spec/models/outage_spec.rb
.....F
Failures:
1) Outage validations is expected to validate that :end_time looks like a number greater than 2020-04-20 12:58:31 -0400
Failure/Error: it { should validate_numericality_of(:end_time).is_greater_than(Time.now) }
Expected Outage to validate that :end_time looks like a number greater
than 2020-04-20 12:58:31 -0400, but this could not be proved.
After setting :end_time to ‹"2020-04-20 12:58:31 -0400"› -- which was
read back as ‹Mon, 20 Apr 2020 16:58:31 UTC +00:00› -- the matcher
expected the Outage to be invalid and to produce the validation error
"must be greater than 2020-04-20 12:58:31 -0400" on :end_time. The
record was indeed invalid, but it produced these validation errors
instead:
* service: ["must exist"]
* start_time: ["can't be blank", "is not a number"]
* reason: ["can't be blank"]
* end_time: ["is not a number"]
As indicated in the message above, :end_time seems to be changing
certain values as they are set, and this could have something to do
with why this test is failing. If you've overridden the writer method
for this attribute, then you may need to change it to make this test
pass, or do something else entirely.
# ./spec/models/outage_spec.rb:16:in `block (3 levels) in <top (required)>'
Finished in 0.23808 seconds (files took 1.77 seconds to load)
6 examples, 1 failure
【问题讨论】:
-
你试图测试一个日期是一个数字,它不是。您可以为此编写自定义验证器。
标签: ruby-on-rails testing rspec factory-bot