首页 > 解决方案 > 为什么应用程序记录会更改我的 RSpec 测试结果

问题描述

对测试来说相当绿色,但我遵循的是一个简单的 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

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

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

标签: ruby-on-railsrubytestingrspecrspec-rails

解决方案


您正在尝试覆盖模型的默认初始化程序并且您以错误的方式进行操作。当您调用newActiveRecord 类时,您需要传递参数散列。要name在模型中有字段,您需要在 DB 模式中定义它。

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

described_class.new(name: "John")

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

使用回调设置它

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 建议的属性 API

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

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

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


推荐阅读