ruby-on-rails – Railstutorial.org验证唯一的电子邮件
在
Ruby on Rails 3教程的6.2.4节中,Michael Hartl描述了一个关于检查电子邮件地址唯一性的警告:如果两个相同的请求及时接近,请求A可以通过验证,然后B通过验证,然后A得到保存,然后B得到保存,你得到两个具有相同值的记录.每个都在检查时有效.
我的问题不在于解决方案(对数据库设置了一个独特的约束,因此B的保存不起作用).这是关于编写测试以证明解决方案有效.我尝试自己编写,但无论我想出什么,只能模仿常规的,简单的唯一性测试. 作为rspec的全新,我的天真方法是编写场景: it 'should reject duplicate email addresses with caveat' do A = User.new( @attr ) A.should be_valid # always valid B = User.new( @attr ) B.should be_valid # always valid,as expected A.save.should == true # save always works fine B.save.should == false # this is the problem case # B.should_not be_valid # ...same results as "save.should" end 但是这个测试在与常规唯一性测试完全相同的情况下通过/失败;编写代码时,B.save.should == false会传递,以便常规测试失败时常规唯一性测试通过并失败. 所以我的问题是“如何编写一个可以验证我正在解决这个问题的rspec测试?”如果答案结果是“它很复杂”,那么我应该看一下不同的Rails测试框架吗? 解决方法
情况很复杂.竞争条件非常糟糕,因为它们很难再现.在内部,保存就是这样的:
>验证. 因此,要重现计时问题,您需要安排两个保存调用重叠,如下所示(伪Rails): a.validate # first half of a.save b.validate # first half of b.save a.write_to_db # second half of a.save b.write_to_db # second half of b.save 但是你不能打开保存方法并且非常容易地摆弄它的内部结构. 但是(这是一个很大但是),you can skip the validations entirely:
所以,如果你使用 b.save(:validate => false) 你应该只获得“写入数据库”b的一半保存并将数据发送到数据库而无需验证.这应该会触发数据库中的约束违规,我很确定会引发ActiveRecord::StatementInvalid异常,所以我认为你需要查找异常,而不仅仅是从save中返回错误: b.save(:validate => false).should raise_exception(ActiveRecord::StatementInvalid) 您可以将其收紧,以查找特定的异常消息.我没有任何方便测试此测试,因此请在Rails控制台中尝试并适当调整您的规范. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |