新程序员在这里。我是一名正在研究Reddit克隆项目的学生。目前我已被介绍给RSPEC。我必须开始编写自己的模型测试以用于进一步的练习。有问题的模型没有创建,它将在下一个任务中。有人可以检查一下我是否做得正确吗?
在下一个检查点,我们将添加一个投票模型。这个模型会 以包含验证为特色。包含验证确保a vote的value属性为1或-1。如果投票已初始化 除了任何其他值,它将无法保存。
- 创建VoteSpec:
醇>
规格/模型/ vote_spec.rb
describe Vote do
describe "validations" do
describe "value validation" do
it "only allows -1 or 1 as values" do
# your expectations here
end
end
end
end
编写一个断言验证的规范按预期工作。
使用RSpec的expect()。到eq()语法。你可能还记得中的规格 在Ruby练习中,你可以断言某些东西应该等于假 或者是真的。
您将无法运行测试,因为我们没有 生成了我们正在测试的模型。
以下是我的实施:
describe Vote do
describe "validations" do
before do
2.times { @vote.create(value: 1) }
3.times { @vote.create(value: -1) }
2.times { @vote.create(value: 3) }
end
describe "value validation" do
it "only allows -1 or 1 as values" do
expect ( @vote.value ).to eq(-1)
end
it "only allows -1 or 1 as values" do
expect ( @vote.value ).to eq(1)
end
end
end
end
最好的问候。
编辑:这是一个修订版:
describe Vote do
describe "validations" do
before do
2.times { Vote.create(value: 1) }
3.times { Vote.create(value: 0) }
2.times { Vote.create(value: 3) }
end
describe "value validation" do
it "only allows -1 as value" do
expect ( @vote.value ).to eq(-1)
end
it "only allows 1 as value" do
expect ( @vote.value ).to eq(1)
end
it "it prohibits other values" do
expect( @vote.value ).to_not be_valid
end
end
end
end
我也试过这个代码,它起初工作但现在在下一个任务中失败了:
require 'rails_helper'
describe Vote do
describe "value validation" do
it "allows -1" do
value = Vote.create(value: -1)
expect(value).to be_valid
end
it "allows +1" do
value = Vote.create(value: +1)
expect(value).to be_valid
end
it "prohibits other values" do
value = Vote.create(value: 0)
expect(value).to_not be_valid
end
end
end
▶ rspec spec
...FFF
Failures:
1) Vote value validation allows -1
Failure/Error: value = Vote.create(value: -1)
NoMethodError:
undefined method `update_rank' for nil:NilClass
# ./app/models/vote.rb:12:in `update_post'
# ./spec/models/vote_spec.rb:7:in `block (3 levels) in <top (required)>'
2) Vote value validation allows +1
Failure/Error: value = Vote.create(value: +1)
NoMethodError:
undefined method `update_rank' for nil:NilClass
# ./app/models/vote.rb:12:in `update_post'
# ./spec/models/vote_spec.rb:12:in `block (3 levels) in <top (required)>'
3) Vote value validation prohibits other values
Failure/Error: expect(value).to eq(false)
expected: false
got: #<Vote id: nil, value: 0, user_id: nil, post_id: nil, created_at: nil, updated_at: nil>
(compared using ==)
# ./spec/models/vote_spec.rb:18:in `block (3 levels) in <top (required)>'
Finished in 0.30485 seconds (files took 3.28 seconds to load)
6 examples, 3 failures
Failed examples:
rspec ./spec/models/vote_spec.rb:6 # Vote value validation allows -1
rspec ./spec/models/vote_spec.rb:11 # Vote value validation allows +1
rspec ./spec/models/vote_spec.rb:16 # Vote value validation prohibits other values
答案 0 :(得分:3)
在这个稍微特殊的情况下,您可以使用绝对值。
it "only allows -1 or 1 as values" do
expect ( @vote.value.abs ).to eq(1)
end
答案 1 :(得分:2)
您可以将RSpec compound expectations与or
一起使用:
it "only allows -1 or 1 as values" do
expect ( @vote.value ).to eq(1).or eq(-1)
end
答案 2 :(得分:1)
Jonathan,根据您的指示,您应该尝试保存/验证投票,看看结果是真还是假。您还应该使用let
来使代码更清晰,并使用build
以确保在您明确这样做之前不会保存投票。以下是我将如何处理这种情况:
describe Vote do
describe "validations" do
let(:vote) { Vote.new(value: vote_value) }
context "when the value is 1" do
let(:vote_value) { 1 }
it "successfully saves" do
expect(vote.save).to eq(true)
end
end
context "when the value is -1" do
let(:vote_value) { -1 }
it "successfully saves" do
expect(vote.save).to eq(true)
end
end
context "when the value is 0" do
let(:vote_value) { 0 }
it "does not save" do
expect(vote.save).to eq(false)
end
end
end
end
可以vote.save
vote.valid?
答案 3 :(得分:0)
在我看来,测试的内容已经在任务本身中了:
此模型将包含包含验证。包含验证可确保投票的值属性为1或-1。如果使用任何其他值初始化投票,则不会保存。
让我们一步一步走:
describe Vote do
describe 'validations' do
it 'should treat -1 vote value as valid' do
# 1. Prepare the environment. That comes right from the task: we need
# to create a model with a vote value of -1.
# 2. Do something. Again, from the task: let's try saving it.
# 3. Verify the result. From the tasks again: it should save.
end
end
end
现在我们知道该怎么做了,让我们去写一些代码:
describe Vote do
describe 'validations' do
it 'should treat -1 vote value as valid' do
# 1. Prepare the environment. That comes right from the task: we need
# to create a model with a vote value of -1.
vote = Vote.new(value: -1)
# 2. Do something. Again, from the task: let's try saving it.
result = vote.save
# (according to ActiveRecord specifications `.save` returns
# `true` when it succeeds saving, and `false` otherwise.
# 3. Verify the result. From the tasks again: it should save.
expect(result).to be_true
end
it 'should treat 1 vote value as valid' do
# Prepare the environment
vote = Vote.new(value: 1)
# Do something
result = vote.save
# Verify the result
expect(result).to be_true
end
it 'should treat 0 vote value as invalid' do
# Prepare the environment
vote = Vote.new(value: 0)
# Do something
result = vote.save
# 3. Verify the result. From the task: it should *not* save.
expect(result).to be_false
end
end
end
现在我们有适合您需求的代码:它验证模型。它有几个问题:
value
字段让我们解决这些问题(我将删除评论):
describe Vote do
describe 'validations' do
let(:overrides) { { } }
let(:params) { { value: 1 }.merge(overrides) } # valid by default
subject { Vote.new(params).save }
context 'vote == -1 is valid' do
let(:overrides) { { value: -1 } } # override one parameter
it { is_expected.to be_true }
end
context 'vote == 1 is valid' do
let(:overrides) { { value: 0 } }
it { is_expected.to be_true }
end
context 'vote == 0 is invalid' do
let(:overrides) { { value: 0 } }
it { is_expected.to be_false }
end
end
end
如果需要,您可以通过至少两种方式使其更清晰,更易读:
使用第三方库,它们基本上包含已经为您编写的帮助程序。他们会将您的验证验证码更改为:
describe Vote do
it { is_expected.to validate_inclusion_of(:value).in_array([-1, 1]) }
end
干净,对吧? :)但我不认为这是你在本练习中所期望的。
希望这有帮助!