RSPEC测试无法为嵌套资源

时间:2015-06-22 20:44:56

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

我有一个名为“参数”的资源,它嵌套在我的API中的“tests”下。关系如下:“测试有很多参数”。我按照以下方式构建了我的路线

  

测试/:为test_id /参数/:parameter_id

我的rake routes给出了:

      test_parameters GET    /tests/:test_id/parameters(.:format)                parameters#index {:format=>:json}
                      POST   /tests/:test_id/parameters(.:format)                parameters#create {:format=>:json}
   new_test_parameter GET    /tests/:test_id/parameters/new(.:format)            parameters#new {:format=>:json}
  edit_test_parameter GET    /tests/:test_id/parameters/:id/edit(.:format)       parameters#edit {:format=>:json}
       test_parameter GET    /tests/:test_id/parameters/:id(.:format)            parameters#show {:format=>:json}
                      PATCH  /tests/:test_id/parameters/:id(.:format)            parameters#update {:format=>:json}
                      PUT    /tests/:test_id/parameters/:id(.:format)            parameters#update {:format=>:json}
                      DELETE /tests/:test_id/parameters/:id(.:format)            parameters#destroy {:format=>:json}

我正在编写简单的测试来测试API的所有典型操作。现在,我的POST / CREATE给了我一个非常令人费解的错误。

Failures:

  1) ParametersController POST create a new parameter with valid attributes successfully with name and times
     Failure/Error: post :create, :test_id => @test.id, parameter: parameter.attributes, format: :json
     NoMethodError:
       undefined method `parameter_url' for #<ParametersController:0x000001072b4280>
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_dispatch/routing/polymorphic_routes.rb:220:in `polymorphic_method'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_dispatch/routing/polymorphic_routes.rb:114:in `polymorphic_url'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_dispatch/routing/url_for.rb:163:in `url_for'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_controller/metal/rendering.rb:95:in `_process_options'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_controller/metal/streaming.rb:200:in `_process_options'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_controller/metal/renderers.rb:43:in `block in _render_to_body_with_renderer'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_controller/metal/renderers.rb:41:in `_render_to_body_with_renderer'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_controller/metal/renderers.rb:37:in `render_to_body'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/abstract_controller/rendering.rb:25:in `render'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_controller/metal/rendering.rb:16:in `render'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_controller/metal/instrumentation.rb:44:in `block (2 levels) in render'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/activesupport-4.2.2/lib/active_support/core_ext/benchmark.rb:12:in `block in ms'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/activesupport-4.2.2/lib/active_support/core_ext/benchmark.rb:12:in `ms'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_controller/metal/instrumentation.rb:44:in `block in render'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_controller/metal/instrumentation.rb:87:in `cleanup_view_runtime'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/activerecord-4.2.2/lib/active_record/railties/controller_runtime.rb:25:in `cleanup_view_runtime'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_controller/metal/instrumentation.rb:43:in `render'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/responders-2.1.0/lib/action_controller/responder.rb:258:in `display'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/responders-2.1.0/lib/action_controller/responder.rb:214:in `api_behavior'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/responders-2.1.0/lib/action_controller/responder.rb:191:in `rescue in to_format'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/responders-2.1.0/lib/action_controller/responder.rb:185:in `to_format'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/responders-2.1.0/lib/action_controller/responder.rb:163:in `respond'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/responders-2.1.0/lib/action_controller/responder.rb:156:in `call'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/responders-2.1.0/lib/action_controller/respond_with.rb:203:in `respond_with'
     # ./app/controllers/parameters_controller.rb:13:in `create'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_controller/metal/implicit_render.rb:4:in `send_action'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/abstract_controller/base.rb:198:in `process_action'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_controller/metal/rendering.rb:10:in `process_action'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/abstract_controller/callbacks.rb:20:in `block in process_action'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/activesupport-4.2.2/lib/active_support/callbacks.rb:117:in `call'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/activesupport-4.2.2/lib/active_support/callbacks.rb:117:in `call'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/activesupport-4.2.2/lib/active_support/callbacks.rb:555:in `block (2 levels) in compile'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/activesupport-4.2.2/lib/active_support/callbacks.rb:505:in `call'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/activesupport-4.2.2/lib/active_support/callbacks.rb:505:in `call'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/activesupport-4.2.2/lib/active_support/callbacks.rb:92:in `_run_callbacks'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/activesupport-4.2.2/lib/active_support/callbacks.rb:776:in `_run_process_action_callbacks'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/activesupport-4.2.2/lib/active_support/callbacks.rb:81:in `run_callbacks'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/abstract_controller/callbacks.rb:19:in `process_action'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_controller/metal/rescue.rb:29:in `process_action'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/activesupport-4.2.2/lib/active_support/notifications.rb:164:in `block in instrument'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/activesupport-4.2.2/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/activesupport-4.2.2/lib/active_support/notifications.rb:164:in `instrument'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_controller/metal/instrumentation.rb:30:in `process_action'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_controller/metal/params_wrapper.rb:250:in `process_action'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/activerecord-4.2.2/lib/active_record/railties/controller_runtime.rb:18:in `process_action'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/abstract_controller/base.rb:137:in `process'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionview-4.2.2/lib/action_view/rendering.rb:30:in `process'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_controller/test_case.rb:632:in `process'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_controller/test_case.rb:65:in `process'
     # /Users/naseem.alnaji/.rvm/gems/ruby-2.1.1/gems/actionpack-4.2.2/lib/action_controller/test_case.rb:514:in `post'
     # ./spec/controllers/parameters_controller_spec.rb:34:in `block (5 levels) in <top (required)>'
     # ./spec/controllers/parameters_controller_spec.rb:33:in `block (4 levels) in <top (required)>'

我已经尝试更改我提交POST的格式,但没有改变任何内容。现在,我的rspec测试看起来像这样:

    "spec/controllers/parameters_controller_spec.rb"
    require 'spec_helper'
    describe ParametersController do
      before :each do
        @test = FactoryGirl.create(:test, id: 1, name: 'Eccentric Tech')
        @test.save
      end

      # ...

      describe 'POST create a new parameter' do
        context 'with valid attributes' do
          it 'successfully with name and times' do
            parameter = FactoryGirl.build(:parameter)
            expect {
              post :create, :test_id => @test.id, parameter: parameter.attributes, format: :json
            }.to change(Parameter, :count).by(1)
          end
        end
        context 'with invalid attributes' do
          it 'fails without a name' do
            parameter = FactoryGirl.build(:no_name_parameter)
            expect {
              post :create, :test_id => @test.id, parameter: parameter.attributes, format: :json
            }.to change(Parameter, :count).by(0)
          end
          it 'fails without belonging to a test' do
            parameter = FactoryGirl.build(:no_test_parameter)
            expect {
              post :create, :test_id => @test.id, parameter: parameter.attributes, format: :json
            }.to change(Parameter, :count).by(0)
          end
        end
      end

      # ...

    end

我的工厂:

"spec/factories/parameters.rb"
require 'faker'

FactoryGirl.define do
  factory :parameter do |f|
    f.name { "#{Faker::Hacker.noun}" }
    f.value { Faker::Number.number(2) }
    f.test_id { 1 }
  end

  factory :no_name_parameter, parent: :parameter do |f|
    f.name nil
    f.value { Faker::Number.number(2) }
    f.test_id { 1 }
  end

  factory :no_test_parameter, parent: :parameter do |f|
    f.name { "#{Faker::Hacker.noun}" }
    f.value { Faker::Number.number(2) }
    f.test_id nil
  end
end

最后,我的控制器:

class ParametersController < ApplicationController
  respond_to :json

  def index
    respond_with Parameter.all
  end

  def show
    respond_with Parameter.find(params[:id])
  end

  def create
      respond_with Parameter.create(parameter_params)
  end

  def update
    respond_with Parameter.update(params[:id], parameter_params)
  end

  def destroy
    respond_with Parameter.destroy(params[:id])
  end

  private
    def parameter_params
      params.require(:parameter).permit(:name, :value, :test_id)
    end
end

routes.rb中:

Rails.application.routes.draw do
  scope :defaults => { :format => :json } do
    resources :services do
      resources :tests
    end

    resources :tests do
      resources :parameters
      resources :singular_results
      resources :dataset_results
    end
  end
end

1 个答案:

答案 0 :(得分:0)

我自己解决了这个问题,但我不知道为什么会这样。如果有人可以解释,请执行:)

我所做的就是对我的控制器进行一些小改动:

import java.nio.{ByteBuffer, ByteOrder}

def bytesToShort(byte1: Byte, byte2: Byte) : Short = {
  ByteBuffer
    .allocate(2)
    .order(ByteOrder.LITTLE_ENDIAN)
    .put(byte1)
    .put(byte2)
    .getShort(0)
}

val bytes = Array[Byte](1, 2, 3, 4)
bytes.grouped(2).map {
  case Array(one) => bytesToShort(one, 0.toByte)
  case Array(one, two) => bytesToShort(one, two)
}.toArray

找到了一个很好的解释:http://meowcrypt.com/