简体   繁体   English

使用不带辅助工具的rspec在Rails模型中测试字段唯一性的验证

[英]Testing the validation of uniqueness of the field in Rails's model using rspec without helper gems

I'm trying to write test to validate the uniqueness of the field in RoR's model. 我正在尝试编写测试以验证RoR模型中字段的唯一性。

I am working on Ruby on Rails apps which I use to practice my skills in TDD. 我正在研究Ruby on Rails应用程序,该应用程序用于在TDD中练习我的技能。 I have used Internet as my resource so far. 到目前为止,我已经使用Internet作为我的资源。 I'm writing testing on validation for model.I will not be using 'shoulda', 'FactoryGirl' (and etc) gems. 我正在编写关于模型验证的测试,我不会使用'shoulda','FactoryGirl'(等等)gems。 I know using those gems will save me lots of coding but I will use those gems eventually. 我知道使用这些gems可以节省很多代码,但最终我会使用这些gems。 I want to learn how to write rspec test on it own without gems to help me understand how to write testing. 我想学习如何自己编写没有rem的rspec测试,以帮助我理解如何编写测试。 I am doing good so far until 'uniqueness' testing. 到目前为止,在“唯一性”测试之前,我一直做得很好。

How do I create test to validate the uniquenss of the 'email' field in 'User' model without using 'shoulda', 'FactoryGirl' (and etc) gems. 我如何创建测试以验证“用户”模型中“电子邮件”字段的唯一性,而不使用“ shoulda”,“ FactoryGirl”(等)gem。 I know using those gems will save lots of coding but I will use those gems eventually. 我知道使用这些gems可以节省很多代码,但最终我会使用这些gems。 I want to learn how to write rspec test on it own without gems to help me understand how to write testing. 我想学习如何自己编写没有rem的rspec测试,以帮助我理解如何编写测试。

Most 'answer' to this questions on Stackoverflow (and elsewhere on the Net) includes the use of those helper gems. 在Stackoverflow(以及网络上的其他地方)上,对该问题的大多数“答案”都包括使用这些辅助工具。 But find no answer to this without gems. 但是,如果没有宝石,找不到答案。

Here is model, User.rb ``` 这是模型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

``` ```

how do I write to test for uniqueness. 如何写以测试唯一性。 Should I use something else other than 'subject' to test against? 除了“主题”以外,我还应该使用其他东西进行测试吗? Remember, I don't want a solution that use gems (Shoulda/FactoryGirl/etc) this time. 请记住,这次我不需要使用宝石的解决方案(Shoulda / FactoryGirl / etc)。

I've been at it for the last few days and no luck. 最近几天我一直在这里,没有运气。 Any solution? 有什么办法吗? And where is the best tutorial on rspec on Ruby on Rails? 在Ruby on Rails上关于rspec的最佳教程在哪里?

To test for uniqueness, first you have to create a user with same email as used in subject . 要测试唯一性,首先必须创建一个用户,该用户的电子邮件与subject使用的电子邮件相同。 Then, your subject would be invalid because of uniqueness validation on email. 然后,由于电子邮件上的唯一性验证,您的subject将无效。

Something like: 就像是:

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

Ok I got it working. 好吧,我知道了。 Ok, at the suggestion of @Jagdeep Singh, I wrote this test: 好的,在@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

``` and it seems to pass the test. 似乎通过了测试。 I added other test to test valid uniqueness. 我添加了其他测试来测试有效的唯一性。 Thanks for the help. 谢谢您的帮助。

I decided to rewrite whole test to make use of context to make it more clear and readable. 我决定重写整个测试,以利用context使其更清晰易读。 Here is my rewrite: 这是我的重写:

# 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

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

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