我有一个模型,我在其中实施了验证以防止在设置初始值后(在对象创建期间)发生更改.
I have a model where I implemented a validate to prevent change after the initial value has been set (during the object creation).
它是这样工作的:
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.
但是我的 Rspec 测试失败了.
实际上我知道它不起作用,因为 on::validate 存在问题.
确实没有'on::validate',测试通过,但当然我不能只删除'on::update',因为我只希望用户在初始创建后不能编辑它交易).
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但我收到此 rspec 错误:
but I get this rspec error:
Failure/Error: expect(deal).to have(1).errors_on(:quantity) expected 1 errors on :quantity, got 0我将使用下面的打印变量":p Deal 来向您展示为什么我确定这是由于 :update 在测试中不起作用.
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.
第一:如果我在更新之前放置'p deal',让我们看看deal对象的值:
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我得到以下输出(我们看到一切正常:数量确实是 10)
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>第二:现在让我们在测试中尝试更新数量"值后移动p 交易"
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现在输出是:(我们看到与我们预期的相反,因为代码中的验证::update,不幸的是,Rspec 测试确实设法更新了数量的值):
#<title: "Neque porro quisquam est qui dolorem", description: "lorem ipsum lorem ipsum lorem ipsum lorem ipsum lo...", quantity: 15>所以我不明白为什么在现实中,我手动测试并且无法更新,但是在我的 rspec 测试套件中它确实更新了!!!
So I don't understand why in reality, I tested manually and can not update, but in my rspec test suite it does update!!!
几个小时来理解它但没有成功......我试图找到一些在线资源,有些人说on::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.
请帮忙.
推荐答案我猜由于其他验证,在调用 create 方法时不会保存条目.您可以尝试使用 rails c 打开控制台并评估以下内容:
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编辑
这个测试应该通过:
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但这些不应该:
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更多推荐
'on::update' 的 Rspec 测试验证不起作用(Rails4/Rspec 3)
发布评论