Ruby on rails rails-FactoryGirl保留的对象在控制器中不可用

Ruby on rails rails-FactoryGirl保留的对象在控制器中不可用,ruby-on-rails,rspec,mongoid,factory-bot,database-cleaner,Ruby On Rails,Rspec,Mongoid,Factory Bot,Database Cleaner,我正在为管理员命名空间中的控制器编写测试。使用RSpec(3.5.0)、FactoryGirl(4.8.0)、DatabaseCleaner(1.5.3)和Mongoid(6.0.3) 问题是这些测试的行为很奇怪。测试GET index请求时,FactoryGirl生成的对象被成功创建并持久化。但是,控制器似乎没有找到它们 我有三个不同的控制器。三分之二的人有这个问题,而第三个问题很有魅力。代码是相同的(除了命名),唯一的区别是工作控制器的资源是嵌套的 附件工程: describe "GET #

我正在为管理员命名空间中的控制器编写测试。使用RSpec(3.5.0)、FactoryGirl(4.8.0)、DatabaseCleaner(1.5.3)和Mongoid(6.0.3)

问题是这些测试的行为很奇怪。测试
GET index
请求时,FactoryGirl生成的对象被成功创建并持久化。但是,控制器似乎没有找到它们

我有三个不同的控制器。三分之二的人有这个问题,而第三个问题很有魅力。代码是相同的(除了命名),唯一的区别是工作控制器的资源是嵌套的

附件工程:

describe "GET #index", get: true do

    let (:accessory) { FactoryGirl.create(:accessory) }

    before do
      get :index, params: { category_id: accessory.category_id.to_s }, session: valid_session, format: :json
    end

    it "responses with OK status" do
      expect(response).to have_http_status(:success)
    end

    it "responses with a non-empty Array" do
      expect(json_body).to be_kind_of(Array)
      expect(json_body.length).to eq(1)
    end

    it "responses with JSON containing accessory" do
      expect(response.body).to be_json
      expect(json_body.first.with_indifferent_access).to match({
          id: accessory.to_param,
          name: 'Test accessory',
          description: 'This is an accessory',
          car_model: 'xv',
          model_year: '2013',
          images: be_kind_of(Array),
          category_id: accessory.category.to_param,
          dealer_id: accessory.dealer.to_param,
          url: be_kind_of(String)
        })
    end
  end
而类别的一个不:

describe "GET #index", get: true do

    let (:category) { FactoryGirl.create(:category) }

    before do
      get :index, params: {}, session: valid_session, format: :json
    end

    it "responses with OK status" do
      expect(response).to have_http_status(:success)
    end

    it "responses with a non-empty Array" do
      expect(json_body).to be_kind_of(Array)
      expect(json_body.length).to eq(1)
    end

    it "responses with JSON containing category" do
      expect(response.body).to be_json
      expect(json_body.first.with_indifferent_access).to match({
          id: category.to_param,
          name: 'Test category',
          image: be_kind_of(String),
          url: be_kind_of(String)
        })
    end
  end
正如您所看到的,逻辑是相同的:在
before
钩子中发出请求,并使用
let
设置对象

另一件奇怪的事情是,
getshow
test对具有相同逻辑的类别进行测试,效果非常好

在这些问题(,)中,他们说这可能是由于数据库清理策略,应该使用
截断
而不是
事务
策略。这是因为Mongoid只允许
截断
。我也没有使用支持JavaScript的测试,并特别告诉rspec使用\u transactional\u fixtures=false

FactoryGirl和DatabaseCleaner的RSpec配置:

RSpec.configure do |config|
  config.include FactoryGirl::Syntax::Methods

  config.before(:suite) do
    DatabaseCleaner.strategy = :truncation
    DatabaseCleaner.clean_with(:truncation)
  end

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

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

  config.after(:each) do
    DatabaseCleaner.clean
  end
end
我可以通过发出请求并在每个示例中创建一个对象来通过这些测试,而不是在之前使用
。但我认为它应该与他们合作

默认情况下,控制器索引方法为:

def index
  @thing = Thing.all
end

你对这种奇怪的行为有什么想法吗?

请尝试
让我们看看而不是

请注意,
let
是惰性计算的。调用
Category.to_param
时会生成类别数据。它不存在于
之前的
块中


另请参见

哦,对了!难以置信,我没有注意到我在工作示例中实际上调用了对象。非常感谢,@zaru!