【问题标题】:Rails Test w/ Minitest Reporter - NoMethodError: undefined method + ActionController::UrlGenerationError: No route matches带有 Minitest Reporter 的 Rails 测试 - NoMethodError:未定义的方法 + ActionController::UrlGenerationError:没有路由匹配
【发布时间】:2015-09-01 22:32:42
【问题描述】:

我正在学习 Rails,并且对测试非常陌生,但到目前为止,我已经设法构建了一些错误最少的东西。但是,我遇到的问题是我的测试抱怨找不到方法并且没有路由匹配。

据我了解,测试应该经常基于Hartl's - Railstutorial 3.3 运行。许多 StackO 线程和在线文章似乎都与使用我不使用的测试套件(如 RSpec 等)有关……因此测试配置令人困惑。我的测试套件的设置类似于Hartl's - Railstutorial 3.3,下面是为测试加载的 gem。

gem 'better_errors', '~> 2.1.1'
gem 'binding_of_caller'
gem 'minitest-reporters', '1.0.5'
gem 'mini_backtrace',     '0.1.3'
gem 'guard-minitest',     '2.3.1'
gem 'ruby-prof'

NoMethodError:未定义的方法

Error: (_I have two error similar errors to below_)
ServicesControllerTest#test_should_get_index:
NoMethodError: undefined method 'services' for nil:NilClass
    app/controllers/services_controller.rb:6:in 'index'
    test/controllers/services_controller_test.rb:9:in 'block in <class:ServicesControllerTest>"

服务控制器

def index
  @services = current_tech.services
end

services_controller_test.rb

require 'test_helper'

class ServicesControllerTest < ActionController::TestCase
  setup do
    @service = services(:one)
  end

  test "should get index" do
    get :index
    assert_response :success
    assert_not_nil assigns(:services)
  end
end

我相信我收到此错误的原因是因为Devise。 如果我要在下面设置以下索引操作,则测试将通过。

def index
  @services = Tech.first.services
end

如何更正此问题以通过此测试?


ActionController::UrlGenerationError: 没有路由匹配 {:action=>"show", :controller=>"tech"}

Error:
CarsControllerTest#test_should_get_show:
ActionController::UrlGenerationError: No route matches {:action=>"show", :controller=>"cars"}
    test/controllers/cars_controller_test.rb:5:in `block in <class:CarsControllerTest>

Rake 路线 与汽车有关

tech_cars POST - /techs/:tech_id/cars(.:format) - cars#create
car GET - /cars/:id(.:format) - cars#show

路线

Rails.application.routes.draw do  

  devise_for :customers, controllers: { sessions: 'customers/sessions' }
  devise_for :techs, controllers: { sessions: 'techs/sessions' } 

  resources :techs, :only => [:index, :show], shallow: true do
    resources :cars, only: [:show, :create]
  end

  resources :services, :garages

  root "home#index"

end

cars_controller.rb

class CarsController < ApplicationController
  before_action :set_car

  def show
    @garage = Garage.find(params[:id])
    @tech = @tech.service.car.id
  end

  def create
    @garage = Garage.create(tech_first_name: @car.service.tech.first_name,
                                  customer_id: current_customer.id,
                                  customer_street_address: current_customer.street_address,
                                  customer_city: current_customer.city,
                                  customer_state: current_customer.state,
                                  customer_zip_code: current_customer.zip_cod)

    if @garage.save
      redirect_to techs_path, notice:  "Working" 
    else
      redirect_to techs_path, notice:  "Uh oh, flat tire" 
    end
  end

  private

  def set_car
    @car = Car.find(params[:id])
  end

  def car_params
    params.permit(:service_name, :garage_photo)
  end
end

cars_controller_test.rb

require 'test_helper'

class CarControllerTest < ActionController::TestCase
  test "should get show" do
    get :show
    assert_response :success
  end
end

cars.html.erb(仅页面上的链接)

<%= button_to 'View Garage', tech_cars_path(tech_id: @car.service.tech.id, id: @car) %>
<%= link_to 'Back to tech', tech_path(@car.service.tech.id) %>

如您所知,我在 Cars 控制器中构建 Garage 而不是 Car 对象。这会是测试的问题吗?我的应用程序功能正常。附带说明一下,我也很难将 car_params 强参数关联到实例变量,但这是另一个 StackO 帖子。


*test/test_helper.rb

ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
require "minitest/reporters"

Minitest::Reporters.use!

class ActiveSupport::TestCase
  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
  fixtures :all

  # Add more helper methods to be used by all tests here...
end

class ActionController::TestCase
  include Devise::TestHelpers
end

我有什么遗漏或配置不正确吗?

请知道我的应用程序似乎工作正常,只是我想抑制这些测试错误。

请告知如何让这些测试错误通过。

谢谢

【问题讨论】:

    标签: ruby-on-rails ruby devise minitest


    【解决方案1】:

    第一期:你的感觉是对的。 Devise 带有Devise::TestHelpers,您已在测试帮助文件中将其混入ActionController::TestCase。它提供的一种方法是sign_in,它可以让您在测试过程中欺骗登录用户。假设您有一个名为 Tech 的模型并且您遵循标准的 Rails 约定,您需要添加如下内容:

    sign_in techs(:some_tech)
    

    到您的setup 块或在调用get :index 之前直接进入您的测试主体。这将确保current_tech 返回非零值并删除立即的 NoMethodError。

    第二个问题:您的:show 操作需要接收已知Car 的ID 作为URL 的一部分。将您当前对控制器的调用替换为:

    require 'test_helper'
    
    class CarControllerTest < ActionController::TestCase
      setup do
        @car = cars(:some_car)
      end
    
      test "should get show" do
        get :show, id: @car.id
        assert_response :success
      end
    end
    

    【讨论】:

    • 嗨,克里斯,#1 - 感谢您的回复。我不知道固定装置,因为我对测试很陌生。通过Hartl's - tutorial 3.3,Hartl 没有解释任何关于固定装置的信息。收到您的回复后,我仍然有错误。在进行了一些挖掘之后,我需要在测试中包含setup do w/@service = services(:one)。然后在get :index 上方添加@service = services(:one)。这没有返回任何错误。 :)
    • 我是否有理由不能将one: 修改为更有意义的内容,例如service_test 以在services.yml 中引用?我希望能够执行@service = services(:service_test)sign_in techs(:service_test) 之类的操作,但测试会报错。
    • 对于#2 - 我已经添加了你发布的内容 - '@car = cars(:one)' 和 `get :show, id: @car.id` 但我仍然收到错误。 .错误是:` ActionController::UrlGenerationError: No route matches {:action=>"create", :controller=>"cars"}` and NoMethodError: undefined method tech' for nil:NilClass. I figured adding setup do` - @987654344 @ 和 sign_in techs(:one)get :show, id: @car.id 上方,但它仍然会产生错误。请指教。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-29
    • 2015-11-26
    • 1970-01-01
    • 1970-01-01
    • 2019-05-25
    • 1970-01-01
    相关资源
    最近更新 更多