2017-02-10 88 views
8

上下文

我们正在从Rails 3.2.12迁移到4.0.2和Ruby 1.9.3到2.1.8。Rails 3到4迁移唯一性验证问题

我们有很多测试覆盖率来完成RSpec形式的迁移。

问题

一说检查是在卡模型验证的唯一失败的规范的。

validates :mobile, uniqueness: {scope: :program_member_id, message: I18n.t('models.card.error.cardholder_already_has_mobile')}, if: :mobile 

program_member可能只有一个mobile: true卡。

该规范会为会员创建2张卡片,将其中一张转换为移动卡片,然后期待第二张卡片这样做时的验证消息。

let(:program) { FactoryGirl.create(:program) } 
let(:card) { FactoryGirl.create(:card, program: program) } 

context 'when cardholder already has a mobile card' do 
    it 'fails validation' do 
    card2 = FactoryGirl.create(:card, program: program) 
    program_member_user = FactoryGirl.create(:program_member_user, card_number: card2.cardnumber) 
    program_member = program_member_user.program_members.first 

    program_member.cards << card2 
    card2.update_attributes(:mobile => true) 

    program_member.cards << card 
    card.update_attributes(:mobile => true) 

    expect(card.errors.messages).to include(:mobile=>[I18n.t('models.card.error.cardholder_already_has_mobile')]) 
    end 
end 

后市展望:

expected {} to include {:mobile=>["Cardholder already has a mobile card"]} 

当我去我们master分支,该规范通过。

从这个规范工作到失败的唯一因素是Rails 3到4的迁移。

尝试在控制台中运行规范代码才发现该成员有两个移动卡,并且对两个实例都做了card.valid?返回true

问题

有没有什么Rails中4改变了问候的唯一性验证或验证生命周期?

+0

你介意分享一下'register_card'的完整性吗? –

+0

@JanKlimo我已经更新了这个问题,以反映将卡片分配给program_member_user的实际代码。即使我在控制台手动添加所有内容,仍然无法使验证生效。即使删除验证条件也没有效果(即,对非移动卡的唯一性进行验证)。 – fbelanger

+0

嗯,很奇怪,因为我没有看到你的代码有任何问题。我使用问题的简化版本创建了一个测试回购,但验证完全相同。如果你克隆它并运行rspec,测试通过了吗? https://github.com/janklimo/TestUniquenessApp –

回答

1

好吧,我正在做点什么。

我使用相同的Ruby和Rails版本创建了一个测试项目。

https://github.com/frank184/test_uniquness

在这个项目中,我将有一个具有admin列具有类似验证的一个boolean User模型。

validates_uniqueness_of :admin, if: :admin? 

我用shoulda-matchers和rspec来描述期望的结果。

require 'rails_helper' 

RSpec.describe User, type: :model do 
    let(:user) { build :user } 
    subject { user } 

    describe 'validations' do 
    context 'when admin = true' do 
     before(:each) { user.admin = true } 
     it { is_expected.to validate_uniqueness_of(:admin) } 
    end 
    end 
end 

该规范失败,出现以下的输出:

Failures: 

    1) User validations when admin = true should validate that :admin is case-sensitively unique 
    Failure/Error: it { is_expected.to validate_uniqueness_of(:admin) } 

     User did not properly validate that :admin is case-sensitively unique. 
     After taking the given User, whose :admin is ‹true›, and saving it as 
     the existing record, then making a new User and setting its :admin to 
     ‹true› as well, the matcher expected the new User to be invalid, but 
     it was valid instead. 
    # ./spec/models/user_spec.rb:10:in `block (4 levels) in <top (required)>' 

Finished in 0.11435 seconds (files took 0.79997 seconds to load) 
1 example, 1 failure 

我决定,该代码是好的,碰到的Rails 4.1.0,以准确。

规范通过!

bundle update 
rspec 
. 

Finished in 0.09538 seconds (files took 1.28 seconds to load) 
1 example, 0 failures 
+0

请注意,'is_expected'对'subject'有效,所以你应该用'subject'来替换规范中的'user',看它是否仍然有效。 –

+0

请看上面的'describe'验证'do'。 – fbelanger

+0

所以你做得很好。将您的解决方案添加到答案并接受它,以便它可以帮助其他人。 :) –