【问题标题】:FactoryGirl build_stubbed & RSpec - Generates ID but fails to find id when testing Show actionFactoryGirl build_stubbed & RSpec - 生成 ID 但在测试显示操作时找不到 id
【发布时间】:2015-07-24 18:45:26
【问题描述】:

这是我的测试。我得到的错误是 ActiveRecord::RecordNotFound: Couldn't find MedicalStudentProfile with 'id'=1001。我是否正确使用 build_stubbed?

RSpec 测试

RSpec.describe MedicalStudentProfilesController, type: :controller do

 let!(:profile){build_stubbed(:medical_student_profile)}
 let!(:user){build_stubbed(:user)}

 describe 'GET show' do

  it 'should show the requested object' do
   sign_in user
   get :show, id: profile.id
   expect(assigns(:profile)).to eq profile
 end
 end

end

控制器

def show
 @profile = MedicalStudentProfile.find params[:id]
end

【问题讨论】:

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


    【解决方案1】:

    build_stubbed 不会将记录保存到数据库,它只是为模型分配一个虚假的 ActiveRecord id 并存根数据库交互方法(如 save ),这样如果调用它们,测试就会引发异常。尝试使用:

    let!(:profile){create(:medical_student_profile)}

    【讨论】:

    • 谢谢。我检查了 build_stubbed 以加快控制器测试,但它似乎不适用于这里。
    • 您可以模拟或存根 MedicalStudentProfile 类的 find 方法以避免数据库命中。这样您就可以使用模拟来指定控制器的行为,而不是期待数据库结果。如果您想了解更多信息,我绝对向您推荐 Rails 4 Test Prescriptions 这本书。
    • 我知道模拟数据库对测试性能有多大好处,但这种失败不就是集成测试的目的吗?
    • @max 我不会将控制器测试视为集成测试。控制器的职责是成为您获取数据的系统的某些部分和视图之间的管道。但是,传递的特定值不是控制器职责的一部分。所以我们可以使用 mocks 来指定控制器调用适当的方法,而无需有效地调用它们。如果我想编写集成测试,我会使用像 capybara 这样的工具编写端到端测试。这样我将从外部覆盖整个系统。
    【解决方案2】:

    build_stubbed 不会将记录保存到数据库中——它只是对模型进行存根,使其表现得就像它已被持久化一样。这对于模型规范或您实际上不与数据库交互的其他场景非常有用。

    但对于请求和控制器规范,您需要使用 create 以便您的控制器可以从数据库中加载记录。

    let!(:profile){ create(:medical_student_profile) }
    let!(:user){ create(:user) }
    

    【讨论】:

    • 谢谢!我不确定是否可以将它们用于控制器规格。
    猜你喜欢
    • 2016-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-17
    • 1970-01-01
    相关资源
    最近更新 更多