为什么申请记录改变了我的 RSpec 测试结果

Why is Application Record changing my RSpec Test result

测试还算绿色,但我正在学习一门简单的 udemy 课程。我使用 RSpec 文档在 rails 中设置 RSpec 来尝试一些测试。但是我遇到了一个我一生都无法弄清楚的问题...

require "rails_helper"

RSpec.describe User, type: :model do
  subject { described_class.new("John") }

  it "initializes a name" do
    expect(subject.name).to eq("John")
  end

  context "with no argument" do
    subject { described_class.new }

    it "should default to Bill as the name" do
      expect(subject.name).to eq("Bill")
    end
  end
end

# This is my test code. 

# This is my User model. 

class User < ApplicationRecord
  attr_reader :name

  def initialize(name = "Bill")
    @name = name
  end
end

当我 运行 测试失败时,它说第二个测试没有返回 Bill,而是 'nil'。但是,在我的用户模型中,如果我删除 < Application Record 它会通过...此外,如果我在初始化中添加第二个参数,它会随机通过默认测试并在第一个返回默认名称时失败...我'我完全困惑,因为我一直在学习没有 ApplicationRecord 的测试,这似乎是它失败的部分。我尝试将主题更改为 let(:testing){User.new} 但这不起作用。在这里非常感谢任何帮助,因为我似乎无法通过 google.

找到它

让你知道我的 GemFile 中的 :development, :test 部分包含 gem 'rspec-rails', '~> 4.0.0'。

您正在尝试覆盖模型的默认初始值设定项,但您做错了。当您在 ActiveRecord class 上调用 new 时,您需要传递参数的哈希值。要在模型中包含 name 字段,您需要在数据库模式中定义它。

为第一个测试用例创建 User 的实例应该如下所示:

described_class.new(name: "John")

我看到了这些为属性设置默认值的方法:

使用callback

设置
class User < ApplicationRecord
  after_initialize :set_name

  private

  def set_name
    self.name ||= 'Bill' # Set name to Bill if it is nil
  end
end

覆盖 initialize 方法。

# Please avoid this approach
class User < ApplicationRecord
  def initialize(*args)
    super # This will initiate default behaviour of a model
    self.name ||= 'Bill' 
  end
end

按照@engineersmnky 的建议使用attributes API

class User < ApplicationRecord
  attribute :name, :string, default: 'Bill'
end

我强烈建议使用回调或属性 API 方法来避免破坏默认行为。

在那之后,我相信你的测试应该会通过。