2012-07-06 1 views
0

stackoverflow에 대한 첫 번째 게시물은 noob-like와 관련하여 미리 사과합니다.기능 테스트는 중첩 된 매개 변수와 작동하지 않습니다

나는 기능 테스트 중 하나에서 오류가 발생했으며 몇 시간이 지난 후에도이를 전달하는 방법을 찾지 못했습니다.

간단히 말해, invoice_schedule은 입니다. 그런 다음 invoice_milestones의 속성은 estimate_percentage (정수)입니다. 내 모델 models/invoice_schedule.rb은 모두 estimate_percentages의 합계가 100이되어야 함을 요구하는 유효성 검사가 있습니다.

언제든지 invoice_schedule 만들기 작업에 대한 기능 테스트가 실패합니다. 아래의 현재 코드를 사용하면 대신 오류가 발생합니다. 내가 지나가고있는 매개 변수로 어떻게 오류가 나는지 알 수 없습니다.

class InvoiceSchedule < ActiveRecord::Base 
    belongs_to :estimate 
    has_many :invoice_milestones, :dependent => :destroy 

    accepts_nested_attributes_for :invoice_milestones, :allow_destroy => true 

    validate :total_must_equal_one_hundred_percent 

    def total_must_equal_one_hundred_percent 
     if total_percent != 100 
      errors.add(:invoice_milestones, "Total must equal 100%") 
     end 
    end 

    def total_percent 
     invoice_milestones.to_a.sum { |item| item.estimate_percentage || 0 } 
    end 
end 

모델/invoice_milestone.rb :

class InvoiceMilestone < ActiveRecord::Base 
    belongs_to :invoice_schedule 
    belongs_to :invoice 

    validates :estimate_percentage, :numericality => {:only_integer => true, :greater_than_or_equal_to => 0, :less_than_or_equal_to => 100} 
end 

또한 estimate has_one :invoice_schedule

어떤 도움이나 제안이 평가됩니다 :)

모델/invoice_schedule.rb을 알게 될 것이다

컨트롤러/invoice_schedules_controller.rb

def create 
    @invoice_schedule = InvoiceSchedule.new(params[:invoice_schedule]) 
    @estimate = Estimate.find_by_id(params[:estimate_id]) 

    respond_to do |format| 
     if @invoice_schedule.save 
     format.html { redirect_to invoice_schedule_path(@invoice_schedule), :flash => {:notice => 'Invoice schedule was successfully created.', :status => 'success'} } 
     format.json { render json: @invoice_schedule, status: :created, location: @invoice_schedule } 
     else 
     format.html { render action: "new" } 
     format.json { render json: @invoice_schedule.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

시험/기능/invoice_schedules_controller_test.rb

setup do 
    @account = accounts(:lorem) 
    @estimate = estimates(:lorem_one) 
    @user = users(:lorem_vendor) 
    @request.host = "#{@account.subdomain}.myapp.local" 
    session[:user_id] = @user.id 
    @invoice_schedule = invoice_schedules(:lorem_one) 
    @invoice_milestone = invoice_milestones(:lorem_one) 
    @data_estimate = estimates(:lorem_two) 
    @data_invoice_schedule = @invoice_schedule.attributes.merge({estimate_id: @data_estimate.id}) 
    end 

    test "should create invoice_schedule" do 
    assert_difference('InvoiceSchedule.count') do 
     post :create, :invoice_schedule => { estimate_id: @data_estimate, :invoice_milestone => {estimate_percentage: 100}} 
    end 

    assert_redirected_to estimate_invoice_schedule_path(@estimate, assigns(:invoice_schedule)) 
    end 

설정/routes.rb

require 'subdomain' 

    Accountimize::Application.routes.draw do 

     resources :invoices do 
     member do 
      get 'generateInvoiceFromMilestone' 
     end 
     end 

     resources :users 
     resources :sessions 

     get "sign_up" => "accounts#new", :as => "sign_up" 

     resources :accounts 

     resources :clients do 
     get :client_address, on: :member 
     end 

     resources :estimates do 
     resources :invoice_schedules, :shallow => true 
     end 

     resources :line_items 

     constraints(Subdomain) do 
     match '/' => 'accounts#show' 
     get "log_in" => "sessions#new", :as => "log_in" 
     get "log_out" => "sessions#destroy", :as => "log_out" 
     get "register" => "users#new", :as => "register" 
     end 
     root :to => 'site#index', :as => 'site' 
    end 

오류의 추적 내가 얻을 :

InvoiceSchedulesControllerTest 
    test_should_create_invoice_schedule         ERROR 
     No route matches {:invoice_schedule=>{:estimate_id=>"706507935", :invoice_milestones_attributes=>{"0"=>{:description=>"test", :estimate_percentage=>"100"}}}, :controller=>"invoice_schedules", :action=>"create"} 
     STDERR: 
     Exception `ActionController::RoutingError' at /Users/Matt/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/actionpack-3.1.1/lib/action_dispatch/routing/route_set.rb:465:in `raise_routing_error' 
     /Users/Matt/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/actionpack-3.1.1/lib/action_dispatch/routing/route_set.rb:461:in `rescue in generate' 
     /Users/Matt/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/actionpack-3.1.1/lib/action_dispatch/routing/route_set.rb:453:in `generate' 
     /Users/Matt/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/actionpack-3.1.1/lib/action_dispatch/routing/route_set.rb:494:in `generate' 
     /Users/Matt/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/actionpack-3.1.1/lib/action_dispatch/routing/route_set.rb:490:in `generate_extras' 
     /Users/Matt/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/actionpack-3.1.1/lib/action_dispatch/routing/route_set.rb:486:in `extra_keys' 
     /Users/Matt/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/actionpack-3.1.1/lib/action_controller/test_case.rb:145:in `assign_parameters' 
     /Users/Matt/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/actionpack-3.1.1/lib/action_controller/test_case.rb:438:in `process' 
     /Users/Matt/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/actionpack-3.1.1/lib/action_controller/test_case.rb:49:in `process' 
     /Users/Matt/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/actionpack-3.1.1/lib/action_controller/test_case.rb:370:in `post' 
     test/functional/invoice_schedules_controller_test.rb:35:in `block (2 levels) in <class:InvoiceSchedulesControllerTest>' 
     /Users/Matt/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/activesupport-3.1.1/lib/active_support/testing/assertions.rb:55:in `assert_difference' 
     test/functional/invoice_schedules_controller_test.rb:30:in `block in <class:InvoiceSchedulesControllerTest>' 
     /Users/Matt/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/activesupport-3.1.1/lib/active_support/testing/setup_and_teardown.rb:35:in `block in run' 
     /Users/Matt/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/activesupport-3.1.1/lib/active_support/callbacks.rb:444:in `_run_setup_callbacks' 
     /Users/Matt/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/activesupport-3.1.1/lib/active_support/callbacks.rb:81:in `run_callbacks' 
     /Users/Matt/.rbenv/versions/1.9.3-p194/lib/ruby/gems/1.9.1/gems/activesupport-3.1.1/lib/active_support/testing/setup_and_teardown.rb:34:in `run' 

나 ' 인보이스 추가를 완료하는 데 몇 가지 다른 방법을 시도했습니다. ice_milestone을 기능 테스트에서 새로 작성한 invoice_schedule으로 변경했지만 아무 것도 작동하지 않는 것 같습니다. accepts_nested_attributes_for를 추가하면 왜 위의 라우팅 오류가 발생합니까?

답변

3

두 부분으로되어 있습니다. 먼저 라우팅 측면을 올바르게 가져와야합니다. 당신이 송장 일정을 중첩했기 때문에 내부는 기대 그때 당신이 컨트롤러

estimate = Estimate.find(params[:estimate_id]) 
@invoice_schedule = estimate.invoice_schedules.build params[:invoice_schedule] 
의 라인을 따라 뭔가를한다는 것을 즉, 최상위 (안 내부 params[:invoice_schedules])에서 estimate_id을 공급

post :create, :estimate_id => @data_estimate.id, :invoice_schedule => {...} 

을 필요로 추정

두 번째 부분은 중첩 된 속성과 관련이 있습니다. Rails가 예상하는 것과 일치하는 params 해시를 제공해야합니다. 첫 번째 부분은 해시의 키가 :invoice_milestones_attributes이어야한다는 것입니다.이것은 has_many이기 때문에 해당 값은 해시 배열 또는 해시 해시 (키는 무시됩니다. 예 : 레일스 매개 변수 전달에서 배열과 해시 간의 상호 작용으로 인해 주로 발생합니다)에 이 필요합니다.

post :create, :estimate_id => @data_estimate.id, 
       :invoice_schedule => { 
       :invoice_milestones_attributes => [ 
        {:estimate_percentage => 100} 
       ] 
       } 
+0

대단히 감사합니다. 그러나 내 테스트가 실패했습니다. 다음 줄을 테스트에 사용했습니다. post : create, : estimate_id => @ data_estimate.id, : invoice_schedules => {invoice_milestones_attributes => {0 => {estimate_percentage : 100 }}} total_must_equal_one_hundred_percent 유효성 검사로 인해 테스트가 실패합니다. 그것을 주석 처리하면 테스트가 통과됩니다. 그러나이 유효성 검사를 제거하고 유효성 검사를 추가하여 invoice_schedule에 적어도 하나 이상의 invoice_milestone이 있으면 테스트가 실패하므로 invoice_milestone 특성이 새 invoice_milestone을 작성하지 않음을 나타냅니다. – mmontaruli

+0

거기에 중단 점을 붙여 실제로 추측하는 대신 실제로 발생하는 것을 볼 수 있습니다. –

+0

이렇게 추적하면 도움이됩니다. 도와 주셔서 대단히 감사합니다! – mmontaruli