【问题标题】:Testing the validation of uniqueness of the field in Rails's model using rspec without helper gems使用 rspec 测试 Rails 模型中字段唯一性的验证,而不使用辅助 gem
【发布时间】:2018-10-27 17:58:08
【问题描述】:

我正在尝试编写测试来验证 RoR 模型中字段的唯一性。

我正在开发 Ruby on Rails 应用程序,我用它来练习我的 TDD 技能。到目前为止,我一直使用 Internet 作为我的资源。我正在编写模型验证测试。我不会使用“should”、“FactoryGirl”(等)gem。 我知道使用这些 gem 可以为我节省大量编码,但我最终会使用这些 gem。我想学习如何在没有 gem 的情况下自己编写 rspec 测试,以帮助我了解如何编写测试。到目前为止,在“唯一性”测试之前我做得很好。

如何在不使用“shoulda”、“FactoryGirl”(等)gem 的情况下创建测试来验证“用户”模型中“电子邮件”字段的唯一性。 我知道使用这些 gem 会节省大量编码,但我最终会使用这些 gem。我想学习如何在没有 gems 的情况下自己编写 rspec 测试,以帮助我了解如何编写测试。

在 Stackoverflow(以及网络上的其他地方)上对这个问题的大多数“答案”都包括使用这些辅助 gem。但是没有宝石就找不到答案。

这是模型,User.rb ```

class User < ApplicationRecord
  validate: :name, :email, presence: true
  validates :name, length: { minimum: 2 }
  validates :name, length: { maximum: 50 }
  # validates_format_of :email, with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
  validates :email, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i, on: :create }
  validates :email, uniqueness: true
end

And here is `user_spec.rb`.

require 'rails_helper'

RSpec.describe User, type: :model do
  subject {
    described_class.new(name: 'John', email: 'john@home.xyz')
  }

  describe 'Validation' do
    it 'is valid with valid attributes' do
      expect(subject).to be_valid
    end

    it 'is not valid without name' do
      subject.name = nil
      expect(subject).to_not be_valid
    end

    it 'is not valid without email' do
      subject.email = nil
      expect(subject).to_not be_valid
    end

    (...)

    it 'is invalid if the email is not unique' do
      expect(????????).to_not be_valid
    end

  end
end

```

我如何写来测试唯一性。我应该使用“主题”以外的其他东西进行测试吗?请记住,这次我不想要使用 gems(Shoulda/FactoryGirl/etc)的解决方案。

过去几天我一直在努力,但没有运气。有什么解决办法吗? Ruby on Rails 上关于 rspec 的最佳教程在哪里?

【问题讨论】:

    标签: ruby-on-rails validation rspec tdd validates-uniqueness-of


    【解决方案1】:

    好的,我得到了它的工作。 好的,在@Jagdeep Singh 的建议下,我写了这个测试:

    ```

    context 'when email is not unique' do
      before { described_class.create!(name: 'foo', email: 'john@home.xyz') }
      it {expect(subject).to be_invalid}
    end
    

    context 'when email is unique' do
      before { described_class.create!(name: 'foo', email: 'jane@home.xyz') }
      it {expect(subject).to be_valid}
    end
    

    ``` 它似乎通过了测试。我添加了其他测试来测试有效的唯一性。 谢谢您的帮助。

    我决定重写整个测试以使用context 使其更加清晰易读。 这是我的重写:

    # frozen_string_literal: true
    
    require 'rails_helper'
    
    RSpec.describe User, type: :model do
      subject {
        described_class.new(name: 'John', email: 'john@home.xyz')
      }
    
      describe '.validation' do
    
    
    
        context 'when email is not unique' do
          before { described_class.create!(name: 'foo', email: 'john@home.xyz') }
          it {expect(subject).to be_invalid}
        end
    
        context 'when email is  unique' do
          before { described_class.create!(name: 'foo', email: 'jane@home.xyz') }
          it {expect(subject).to be_valid}
        end
    
      end
    end
    

    【讨论】:

      【解决方案2】:

      要测试唯一性,首先您必须使用与subject 中使用的电子邮件相同的电子邮件创建用户。然后,由于电子邮件的唯一性验证,您的 subject 将无效。

      类似:

      before { described_class.create!(name: 'foo', email: 'john@home.xyz') }
      it 'is invalid if the email is not unique' do
        expect(subject).to be_invalid
      end
      

      【讨论】:

      • 如果就这么简单,那subject { described_class.new(name: 'John', email: 'john@home.xyz') }的意义何在?
      • @JohnTowery 立即查看
      • 注意:不要为其他测试运行此 before 块。将其包装在 context 中。
      猜你喜欢
      • 2017-05-28
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 2011-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多