First RSPEC test, make sure the value is 1 or -1

The new programmer is here. I am a student working on my project, which is a Reddit clone. I am currently familiar with RSPEC. I should start writing my own model tests, which will be used in further exercises. The model in question is not being created; it will be in the next assignment. Can someone please check if I did this correctly?

At the next checkpoint, we will add a voting model. This model has an inclusion check function. Enabling validation ensures that the voice value attribute is 1 or -1. If a vote is started with any other value, it will not be saved.

  • Create VoteSpec:

specifications / models / 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 

Write a specification that claims that checks work properly.

Use RSpec expect () for eq () syntax. As you recall from the specifications in Ruby exercises, you can argue that something must be equal to false or true.

You won’t be able to run tests because we don’t have a model created that we are testing.

Below is my implementation:

 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 

Sincerely.

Editing: here is a revision:

 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 

I also tried with this code, which worked first, but now fails in the following assignment:

 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 
+6
source share
4 answers

In this slightly specific case, you can simply use the absolute value.

  it "only allows -1 or 1 as values" do expect ( @vote.value.abs ).to eq(1) end 
+3
source

You can use RSpec compound expectations with or :

 it "only allows -1 or 1 as values" do expect ( @vote.value ).to eq(1).or eq(-1) end 
+2
source

Jonathan, according to your instructions, you should try to save / confirm the vote and see if the result is true or false. You should also use let to make your code clean and build to make sure that the vote is not saved until you explicitly do it. Here's how I would handle this situation:

 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 

Remember to replace those vote.save with vote.valid?

+1
source

It seems to me that testing is already in the task itself:

In this model, inclusion check will be included. Validation of the inclusion ensures that the value attribute is 1 or -1. If voting is initialized with any other value, it will not be saved.

Go step by step:

 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 try saving it. # 3. Verify the result. From the tasks again: it should save. end end end 

Now that we know what to do, release and write the code:

 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 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 

Now we have code that suits your needs: it validates the model. There are several problems with it:

  • This will not work if there are other checks besides the value field
  • This is not how the specifications are written.
  • A bit more

Let me address them (I would share the comments):

 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 

You can make it even cleaner and more readable in at least two ways if you need it:

  • Deploy your own RSpec helpers.
  • Use third-party libraries, which, in essence, contain those helpers that are already written for you. They will change your validation code to something like:

     describe Vote do it { is_expected.to validate_inclusion_of(:value).in_array([-1, 1]) } end 

    Be careful, yes? :) But I don’t think what is expected of you in this exercise.

Hope this helps!

0
source

Source: https://habr.com/ru/post/987353/


All Articles