0

我正在使用 RSpec、Mongoid DB 和 FactoryGirl。以下是我的course_spec.rbfactory/users.rb

require 'spec_helper'
describe Lesson do
  context "has valid data" do
    before :each do
      @course_template = FactoryGirl.create(:course_template1)
      @user = FactoryGirl.build(:user)
      @course_template.share_with(@user)
      @lesson = FactoryGirl.create(:lesson)
      @course_template.add_lesson(@lesson)
      @course_instance = FactoryGirl.create(:course_instance)
      @course_template.add_course_instance(@course_instance)
    end

    it "has course instances" do
      p @lessons
      @lessons.should respond_to :course_templates
    end

  end
end

工厂/用户.rb

FactoryGirl.define do
  factory :user_lesson, class: User do
    first_name 'Lesson'
    last_name 'User'
    roles ["teacher"]
    email "teacher2@example.com"
    password '12345678'
    password_confirmation '12345678'
  end
end

我在第二次运行以下 rspec 命令时遇到以下故障:

bundle exec rspec 规范/模型/lesson_spec.rb

1) Lesson has valid data has course instances
     Failure/Error: @course_template.share_with(@user)
     Mongoid::Errors::DocumentNotFound:

       Problem:
         Document(s) not found for class User with id(s) 51f9fb3479478f6fcb000002.
       Summary:
         When calling User.find with an id or array of ids, each parameter must match a document in the database or this error will be raised. The search was for the id(s): 51f9fb3479478f6fcb000002 ... (1 total) and the following ids were not found: 51f9fb3479478f6fcb000002.
       Resolution:
         Search for an id that is in the database or set the Mongoid.raise_not_found_error configuration option to false, which will cause a nil to be returned instead of raising this error when searching for a single id, or only the matched documents when searching for multiples.
     # ./lib/shared.rb:29:in `share_new_asset_with'
     # ./lib/shared.rb:51:in `update_or_share_with'
     # ./lib/shared.rb:57:in `share_with'
     # ./spec/models/lesson_spec.rb:9:in `block (3 levels) in <top (required)>'

无法解决这个问题。

4

3 回答 3

0

您可以使用序列来生成唯一的电子邮件:

https://github.com/thoughtbot/factory_girl/wiki/Usage#sequences-and-associations

更换你的

email "teacher2@example.com"

sequence(:email) { |n| "teacher#{ n }@example.com }
于 2013-08-01T06:20:35.073 回答
0

由于您在规范中使用创建(未保存在数据库中) ,因此 Mongoid 找不到User具有以下 id的 。51f9fb3479478f6fcb000002FactoryGirl.build(:user)

这里有2个解决方案:

  • 使用创建用户FactoryGirl.create(:user)(慢,需要写入数据库,但有时需要)
  • 存根User.find操作以返回您的构建用户

    User.stub(:find).and_return(@user)

此外,更喜欢let语法而不是在before块中设置实例变量:

let(:user) { FactoryGirl.build(:user) }

before do
  # ...
end

关于你描述的问题,试试这个:

FactoryGirl.define do

  sequence :email do |n|
    "foo#{n}@bar.com"
  end

  factory :user do
    email
  end

end
于 2013-08-01T07:24:06.313 回答
0

我以更好的方式得到了自己问题的答案。我正在使用数据库清洁器 gem来清理测试数据。

参考Avdi Grimm 的博客,我在这里写的是 MongoDB ORM。

#spec/spec_helper.rb
config.use_transactional_fixtures = false 

这将禁用 rspec-rails 在数据库事务中对测试的隐式包装。

#spec/support/database_cleaner.rb
RSpec.configure do |config|
  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner[:mongoid].strategy = :truncation
  end

  config.before(:each, :js => true) do
    DatabaseCleaner[:mongoid].strategy = :truncation
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end
end

这些步骤有助于在规范运行之前清理测试数据。

于 2013-08-01T09:13:28.160 回答