2017-05-11 11 views
1

컨트롤러의 네임 스페이스에 대한 테스트를 작성하고 있습니다. RSpec (3.5.0), FactoryGirl (4.8.0), DatabaseCleaner (1.5.3) 및 Mongoid (6.0.3) 사용.레일 - FactoryGirl에서 유지되는 객체를 컨트롤러에서 사용할 수 없습니다.

문제는 이러한 테스트가 이상하게 작동한다는 것입니다. GET index 요청을 테스트 할 때 FactoryGirl에서 생성 된 객체가 성공적으로 생성되어 유지됩니다. 그러나 컨트롤러가 찾지 못하는 것 같습니다.

세 컨트롤러가 있습니다. 3 명 중 2 명이이 문제가 있고 세 번째 것은 매력처럼 작동합니다. 코드는 동일하지만 (이름 지정 제외) 유일한 차이점은 작업중인 컨트롤러의 리소스가 중첩되어 있다는 것입니다.

액세서리의 하나가 작동합니다

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을 사용하여 개체를 설정하십시오.

또 다른 이상한 점은 동일한 로직을 가진 카테고리에 대한 GET show 테스트가 완벽하게 작동한다는 것입니다. 이러한 질문 (1, 2)에서

그들은이 때문에 DatabaseCleaner 전략이 될 수있는 말을 한 대신 transaction 전략의 truncation를 사용해야합니다. 몽고 이드 이후로 내가 한 것은 truncation입니다. 그리고 나는 또한 use_transactional_fixtures = false에 자바 스크립트 기반 테스트 및 특별히 말했다 RSpec에를 사용하고 있지 않다

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 

beforelet 대신에 각 예제를 사용하십시오. 하지만 나는 그들과 함께해야한다고 생각합니다.

컨트롤러 인덱스 방법은 기본입니다 :

def index 
    @thing = Thing.all 
end 

은이 이상한 행동에 어떤 생각을 가지고 있습니까?

답변

3

대신 let을 사용해보십시오.

let은 지연 평가됩니다. 카테고리 데이터는 category.to_param에 전화 할 때 생성됩니다. before 블록에는 존재하지 않습니다.

도 참조 https://relishapp.com/rspec/rspec-core/v/3-5/docs/helper-methods/let-and-let

+0

아, 맞아! 내가 실제 예제에서 객체를 실제로 호출하고 있다는 사실을 알지 못했다고는 믿을 수 없습니다. 고마워, @ zaru! – mityakoval