【问题标题】:Explain logic behind this TDD test with Rails?用 Rails 解释这个 TDD 测试背后的逻辑?
【发布时间】:2013-08-29 01:12:23
【问题描述】:

我正在学习 Michael Hartl 的 Rails 教程。

为了验证用户名和电子邮件的存在和长度,首先写,你写:

validates :name,  presence: true, length: { maximum: 50 }
validates :email, presence: true

我可以理解并找到合乎逻辑的,但我不明白的是spec/models/user_spec.rb中的测试:

require 'spec_helper'

describe User do

  before do
    @user = User.new(name: "Example User", email: "user@example.com", password: "foobar", password_confirmation: "foobar")
  end

  subject { @user }

  it { should respond_to(:name) }
  it { should respond_to(:email) }
  it { should respond_to(:password_digest) }
  it { should respond_to(:password) }
  it { should respond_to(:password_confirmation) }
  it { should respond_to(:authenticate) }

  it { should be_valid }

  describe "when name is not present" do
    before { @user.name = " " }
    it { should_not be_valid }
  end

  describe "when name is too long" do
    before { @user.name = "a" * 51 }
    it { should_not be_valid }
  end

  describe "when email is not present" do
    before { @user.email = " " }
    it { should_not be_valid }
  end

    describe "when password is not present" do
        before { @user.password = @user.password_confirmation = " " }
        it { should_not be_valid }
    end

    describe "when password doesn't match confirmation" do
      before { @user.password_confirmation = "mismatch" }
      it { should_not be_valid }
    end

    describe "when password confirmation is nil" do
      before { @user.password_confirmation = nil }
      it { should_not be_valid }
    end

  describe "when email format is invalid" do
    it "should be invalid" do
      addresses = %w[user@foo,com user_at_foo.org example.user@foo. foo@bar_baz.com foo@bar+baz.com]
      addresses.each do |invalid_address|
        @user.email = invalid_address
        @user.should_not be_valid
      end
    end
  end

  describe "when email format is valid" do
    it "should be valid" do
      addresses = %w[user@foo.COM A_US-ER@f.b.org frst.lst@foo.jp a+b@baz.cn]
      addresses.each do |valid_address|
        @user.email = valid_address
        @user.should be_valid
      end
    end
  end

  describe "when email address is already taken" do
    before do
      user_with_same_email = @user.dup
      user_with_same_email.email = @user.email.upcase
      user_with_same_email.save
    end

    it { should_not be_valid }
  end

  describe "with a password that's too short" do
    before { @user.password = @user.password_confirmation = "a" * 5 }
    it { should be_invalid }
  end

  describe "return value of authenticate method" do
    before { @user.save }
    let(:found_user) { User.find_by_email(@user.email) }

    describe "with valid password" do
      it { should == found_user.authenticate(@user.password) }
    end

    describe "with invalid password" do
      let(:user_for_invalid_password) { found_user.authenticate("invalid") }

      it { should_not == user_for_invalid_password }
      specify { user_for_invalid_password.should be_false }
    end
  end
end

这不只是强制一个明显无效的条件,满足should_not be_valid 测试,这个测试到底是什么意思?

【问题讨论】:

  • 确保验证符合您的期望。

标签: ruby-on-rails rspec tdd


【解决方案1】:

该测试旨在确保如果属性值超出可接受的范围,被测试的验证机制将“捕获”并指示记录无效。

【讨论】:

  • 所以如果第一次验证失败(验证:email,presence:true),rails 将引用测试,这是否会失败?我虽然 user_spec.rb 只是用于开发/测试环境,那么它在生产中如何工作?
  • 如果第一次测试失败,RSpec 将报告差异,而不是 Rails。 RSpec 只会检测到 Rails 报告的 valid? 的值与示例预期不匹配。
  • 那么当您说“超出可接受范围”时,是否是用户模型中第一个测试设置的范围?
  • 是的,虽然validates 代码通常不被称为“测试”,但该语言通常保留给不在生产模式下执行的软件,validates 代码做。另请注意,validates 调用执行了该类的首次定义,提供了在 实际 验证发生时使用的信息。
  • 我没有关注你的问题。我假设“第一个验证步骤”是指模型中的第一个 validates 调用。这两个调用都是您的生产代码的一部分。它们告诉 Rails 什么是可接受的模型实例。所有其他的东西都是你的规范的一部分。模型中的任何内容都无法替代您的规范中的任何内容。
猜你喜欢
  • 2012-09-21
  • 2017-05-25
  • 2021-10-17
  • 1970-01-01
  • 1970-01-01
  • 2012-08-30
  • 1970-01-01
  • 1970-01-01
  • 2013-07-27
相关资源
最近更新 更多