我正在学习Rails并且对测试非常新,但到目前为止,我已经设法构建了一些错误最少的东西。但是,我遇到的问题是我的测试是抱怨无法找到的方法,也没有路由匹配。
据我所知,应该经常根据Hartl's - Railstutorial 3.3运行测试。许多StackO线程和在线文章似乎与利用我不使用的测试套件有关,如RSpec等...因此测试配置令人困惑。我的测试套件设置与Hartl's - Railstutorial 3.3类似,下面是为测试而加载的宝石。
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 =&gt;“show”,:controller =&gt;“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>
与汽车相关的耙路
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) %>
正如您可能收集的那样,我正在Garage
控制器中构建Car
而不是Cars
对象。这会是测试的问题吗?我的应用程序运行正常。另外,我也很难尝试将car_params
强参数与实例变量相关联,但那是另一个StackO帖子。
*测试/ 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
是否有我遗漏或未正确配置的内容?
请知道我的应用程序似乎工作正常,我只是想抑制这些测试错误。
请告知如何通过这些测试错误。
由于
答案 0 :(得分:0)
第一期:您的感觉是正确的。 Devise附带Devise::TestHelpers
,您已将ActionController::TestCase
混合到测试助手文件中。它提供的方法之一是sign_in
,它允许您在测试过程中欺骗已登录的用户。假设您有一个名为Tech
的模型并且您遵循标准的Rails约定,那么您需要添加以下内容:
sign_in techs(:some_tech)
在致电setup
之前,到您的get :index
阻止或直接进入您的测试机构。这将确保current_tech
返回非零的内容并删除直接的NoMethodError。
第二个问题:您的:show
操作希望在网址中收到已知Car
的ID。用以下代码替换当前的控制器调用:
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