【问题标题】:How to test if a new record has been created using FactoryGirl in RSpec?如何测试是否已在 RSpec 中使用 FactoryGirl 创建了新记录?
【发布时间】:2017-12-11 05:00:10
【问题描述】:

如何使用 FactoryGirl 为 User.find_user_id 类方法编写测试?

Class User < ActiveRecord::Base

   def self.find_user_id (name)
     result = User.find_or_create_by(name: name)
    return result.id
   end
end

编辑:我第一次没有说清楚。我在测试中想要的只是当我调用User.find_user_id 时,User.find_or_create_by 被击中。

我使用了expect(User).to received(:find_or_create_by),但这会使result = nil 和返回语句return result.id 将导致undefined method 'id' for nil:NilClass 的错误。我正在考虑使用 FactoryGirl 创建一条新记录,这样我就不会收到此错误消息。但我不确定这是否是正确的方法,因为我是 RSpec/Rails 的新手

【问题讨论】:

  • 你应该先弄清楚你想测试什么。在您的情况下,如果您想测试是否创建了新记录,那么您应该考虑how to test the changes of database。如果您想测试从该方法返回的内容,请换一种方式思考。在开始新问题之前参考factory-bot的文档+google。
  • 你为什么要测试FactoryBot(以前的FactoryGirl)是否有效?他们有自己的测试。问题的标题与正文不一致,因为您实际上是在询问如何测试您的 User#find_user_id 方法,这与 FactoryBot 完全无关

标签: ruby-on-rails ruby rspec factory-bot


【解决方案1】:

您可以在 rails 模型中使用 valid? 来检查您的模型规格中的 factoryGirl create 函数

RSpec.describe User, :type => :model do
  let(:user) { FactoryGirl.create(:user) }
  it { is_expected.to be_valid }
end

【讨论】:

  • 这没有回答“如何使用 FactoryGirl 为 User.find_user_id 类方法编写测试?”的问题
  • 这个let(:user) { FactoryGirl.create(:user) } 是我的问题的答案!当数据库中不存在名称时,我无法弄清楚如何进行测试。使用您的let,我能够拥有allow(User).to receive(:find_or_create_by).and_return(user),但我没有获得undefined method 'id' for nil:NilClass。我希望我做对了。非常感谢您回答了一个我一开始不知道该怎么问的模糊问题。
【解决方案2】:

FactoryBot(注意 FactoryGirlrenamed a couple of weeks ago)有一个内置 linter 以确保所有工厂生成有效实例。请参阅他们的文档中的Linting Factories

如何使用 linter 的一个非常简单的示例可能如下所示:

# spec factory_linter_spec.rb
require 'spec_helper'

Rspec.describe 'FactoryBot' do
  it 'creates valid instances' do
    FactoryBot.lint
  end
end

【讨论】:

    【解决方案3】:

    1.您需要User 型号的工厂如下:

    FactoryGirl.define do
      factory :user do
        name: 'Stefen'
      end
    end
    

    2.作为您的类方法find_user_id 返回一个用户的ID,其name 被传递给该方法。所以,规格可以写成如下:

    describe '.find_user_id' do
    
      before do
        @user = FactoryGirl.create(:user)
      end
    
      it 'should find user id by name' do
        find_user_id(@user.name).should eq @user.id
      end
    
    end
    

    3.在rspec中,它应该验证你的类方法find_user_id返回一个id

    【讨论】:

    • 虽然这个答案可能是正确的,但从长远来看,留下一些解释会改善这个问题。
    • 感谢麦克的反馈。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    • 1970-01-01
    相关资源
    最近更新 更多