我正在使用rspec进行测试,我的常见问题是路由 这是我的rspec
describe "POST 'create'" do
describe "success" do
before(:each) do
@user = User.create!(:email => "foo@example.com", :password => "foobar", :password_confirmation => "foobar" )
@car = Car.create!(:brand => "example", :color => "foobar", :model => "foobar", :year =>"2012")
end
it "should create a car" do
lambda do
post :create, :cars => @car, :user_id => @user.id
end.should change(Car, :count).by(1)
end
it "should redirect to the user welcome page" do
post :create, :cars => @car, :user_id => @user.id
response.should redirect_to user_car_path
end
end
end
my routes.rb ...
Estaciones::Application.routes.draw do
root :to => "static_pages#home"
match '/contact', :to=>'static_pages#contact'
match '/about', :to=>'static_pages#about'
devise_for :users
resources :gas_stations
resources :users do
resources :cars do
resources :tanking_logs
end
end
....
更新
当我运行测试时,出现了这个错误:
1) CarsController POST 'create' success should create a car
Failure/Error: post :create, :cars => @car, :user => @user
ActionController::RoutingError:
No route matches {:cars=>"12", :user=>"74", :controller=>"cars", :action=>"create"}
# ./spec/controllers/car_controller_spec.rb:22:in `block (5 levels) in <top (required)>'
# ./spec/controllers/car_controller_spec.rb:21:in `block (4 levels) in <top (required)>'
2) CarsController POST 'create' success should redirect to the user welcome page
Failure/Error: post :create, :cars => @car, :user => @user
ActionController::RoutingError:
No route matches {:cars=>"13", :user=>"75", :controller=>"cars", :action=>"create"}
# ./spec/controllers/car_controller_spec.rb:27:in `block (4 levels) in <top (required)>'
这是我的CarsController
class CarsController < ApplicationController
def new
@user = User.find(params[:user_id])
@car = @user.cars.build
end
def create
@user = User.find(params[:user_id])
@car = @user.cars.build(params[:car])
if @car.save
redirect_to user_car_path(@user, @car), :flash => { :notice => " car created!" }
else
redirect_to new_user_car_path ,:flash => { :notice => " sorry try again :(" }
end
end
...
我用你给我的解决方案编辑了它但仍然没有
这是我的佣金路线
user_cars GET /users/:user_id/cars(.:format) cars#index
POST /users/:user_id/cars(.:format) cars#create
new_user_car GET /users/:user_id/cars/new(.:format) cars#new
edit_user_car GET /users/:user_id/cars/:id/edit(.:format) cars#edit
user_car GET /users/:user_id/cars/:id(.:format) cars#show
PUT /users/:user_id/cars/:id(.:format) cars#update
DELETE /users/:user_id/cars/:id(.:format) cars#destroy
答案 0 :(得分:0)
看起来您的:cars
资源已嵌套在:users
资源中:
resources :users do
resources :cars do
...
如果以这种方式构建路由,那么在调用http动作时也需要指定用户。这不起作用:
post :create, :car => @car
因为它缺少您在控制器中访问的:user_id
:
@user = User.find(params[:user_id])
要解决此问题,请传递:user_id
然后模拟或存根User
以返回用户或模拟用户。
更新:
混合模拟和实际记录通常不是一种好习惯,所以这里是你如何在没有模拟的情况下做到这一点:
before(:each) do
@user = User.create(...)
@car = {:brand => "example", :color => "foobar", :model => "foobar", :year =>"2012" }
end
it "should create a car" do
lambda do
post :create, :car => @car, :user_id => @user.id
end.should change(Car, :count).by(1)
end
it "should redirect to the user welcome page" do
post :create, :car => @car, :user_id => @user.id
response.should redirect_to user_car_path
end
将创建用户所需的任何最小属性插入User.create(...)
。我认为应该这样做。
如果你想用模拟做这个(这通常是更好的做法,为了保持控制器/模型规格分离),这里是a good starting point on how to do it。