简体   繁体   English

在Rails和Rspec中测试before_create字段的唯一性

[英]Testing for uniqueness of before_create field in Rails and Rspec

I have a private method that generates a unique open_id for each user. 我有一个私有方法,可以为每个用户生成一个唯一的open_id。 The open_id is also indexed on the database level. open_id也在数据库级别建立索引。 How do I write a model test for uniqueness in RSpec? 如何编写RSpec中唯一性的模型测试?

before_create: generate_open_id!

def generate_open_id!
      begin
        self.open_id = SecureRandom.base64(64)
      end while self.class.exists?(open_id: self.open_id)
    end

UPDATE: solution based on accepted answer below 更新:基于以下可接受答案的解决方案

def generate_open_id!
      if !self.open_id
        begin
          self.open_id = SecureRandom.base64(64)
        end while self.class.exists?(open_id: self.open_id)
      end
    end

@users = FactoryGirl.create_list(:user, 10)
@user_last = @users.last
subject { @user_last }

it "has a random open_id" do
   base_64_regex = %r{^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$}
   expect(@user_last.open_id).to match base_64_regex
end

it "has a unique open_id" do
   expect {FactoryGirl.create(:user, open_id: @user_last.open_id)}.to raise_error(ActiveRecord::RecordNotUnique)
end

Refactoring your original code will make testing what you're trying to do much easier. 重构原始代码将使测试工作变得更加容易。 Change your generate_open_id! 更改您的generate_open_id! method to this 对此的方法

def generate_open_id!
  (open_id = SecureRandom.base64(64)) unless open_id
end

And now you can test with the following 现在您可以使用以下内容进行测试

# spec/models/some_model_spec.rb
describe SomeModel do
  subject(:some_model){ FactoryGirl.create(:some_model) }

  describe 'open_id attribute' do
    it 'is a random base64 string' do
      base_64_regex = %r{^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$}
      expect(some_model.open_id).to match base_64_regex
    end

    it 'is unique' do
      expect {FactoryGirl.create(:some_model, open_id: some_model.open_id)}.to raise_error(ActiveRecord::RecordInvalid)
    end
  end
end

You can use SecureRandom.uuid that will generate to you unique strings. 您可以使用SecureRandom.uuid来为您生成唯一的字符串。

More info here . 更多信息在这里

Also, you can add validates_uniqueness_of :your_field that will do it for you. 另外,您可以添加validates_uniqueness_of :your_field来为您完成此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM