I have a model where I implemented a validate to prevent change after the initial value has been set (during the object creation).
It works this way:
models/deal.rb
validate :quantity_not_changeable, on: :update
def quantity_not_changeable
if quantity_changed?
errors.add(:quantity,
"Change of the initially defined qty is not possible")
end
end
This works in my app: I created a new Deal, it works. I try to edit it by changing the 'quantity' field, it fails. I try to edit another field (apart from 'quantity'), it works. so all is working.
But my Rspec Test to test it FAILS.
Actually I know it does NOT work because there is a problem with on: : validate.
Indeed WITHOUT the 'on: : validate', the test passes, but of course I can't just remove 'on: :update', as I only want the user not to be able to edit it after the initial creation of the Deal).
describe Deal do
let(:admin_user) { FactoryGirl.create(:admin_user) }
before(:each) do
@attr = {
title: "Neque porro quisquam est qui dolorem",
description: "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum",
quantity: 10
}
end
describe "my test" do
describe "test that nb of quantity can't be changed after initial creation" do
it "fails if initial quantity is changed" do
deal = Deal.create(@attr)
deal.update(quantity: 15)
expect(deal).to have(1).errors_on(:quantity)
end
end
but I get this rspec error:
Failure/Error: expect(deal).to have(1).errors_on(:quantity)
expected 1 errors on :quantity, got 0
I am going to use below "print variable": p Deal to show you WHY I am sure it is due to on: :update which is not working in TESTS.
FIRST: if I place 'p deal' just before updating it, let's see the value of the deal object:
describe "my test" do
describe "test that nb of quantity can't be changed after initial creation" do
it "fails if initial quantity is changed" do
deal = Deal.create(@attr)
p deal
deal.update(quantity: 15)
expect(deal).to have(1).errors_on(:quantity)
end
end
I get the following output (we see that all is normal: quantity is indeed 10)
#<title: "Neque porro quisquam est qui dolorem", description: "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lo...", quantity: 10>
SECOND: now let's move the 'p deal' AFTER my attempt in the test to update the value of 'quantity'
describe "my test" do
describe "test that nb of quantity can't be changed after initial creation" do
it "fails if initial quantity is changed" do
deal = Deal.create(@attr)
deal.update(quantity: 15)
p deal
expect(deal).to have(1).errors_on(:quantity)
end
end
Now the output is:( we see that CONTRARY to what we could expect due to the validate on: :update in the code, the Rspec test does manage unfortunately to update the value of quantity ):
#<title: "Neque porro quisquam est qui dolorem", description: "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lo...", quantity: 15>
So I don't understand why in reality, I tested manually and can not update, but in my rspec test suite it does update!!!
Hours to understand it but to no success...I tried to find some online resources and some say on: :update is a weak way to do things . I really don't know what to do with this weird bug.
Please help.
I guess entry isn't saved when called create
method because of other validation. You can try open up a console with rails c
and evaluate following:
deal = Deal.create(title: 'mytitle', description: 'mydescription', quantity: 10)
deal.persisted?
then if you got false in order to find out what errors were when creating:
deal.errors.messages
EDIT
This test should passes:
it "fails if initial quantity is changed" do
deal = Deal.create(@attr)
deal.update(quantity: 26)
expect(deal.errors.messages).to eq({quantity: ["Change of the initially defined qty is not possible"]})
end
But these should not:
it "exploited test that should not pass because messages hash should not be empty" do
deal = Deal.create(@attr)
deal.update(quantity: 26)
expect(deal.errors.messages.empty?).to eq(true)
end
it "exploited test in other variation" do
deal = Deal.create(@attr)
deal.update(quantity: 26)
expect(deal.errors.messages).to eq({})
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.