2012-08-02 54 views
0

我与RSpec的测试和我永恒的问题是路由 这是我的RSpec的ActionController :: RoutingError使用RSpec

describe "POST 'create'" do 

    describe "success" do 

     before(:each) do 
      @user = User.create!(:email => "[email protected]", :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 

我的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

它看起来像你有你的:cars资源嵌套在里面您:users资源:

resources :users do 
    resources :cars do 
... 

如果你组织你的路线这样,那么你需要调用HTTP动作时,指定用户也是如此。这是行不通的:

post :create, :car => @car 

,因为它缺少一个:user_id,您在控制器访问:

@user = User.find(params[:user_id]) 

为了解决这个问题,通过一个:user_id,然后模拟或存根User返回用户或模拟用户。

UPDATE:

这不是一般的好做法,混合模拟考试和实际的记录,所以这里是你如何能做到这一点不嘲笑:

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

+0

我如何能够残留用户? (因为我没有使用mockha) – Asantoya17 2012-08-02 21:47:22

+0

RSpec内置了stubbing:https://www.relishapp.com/rspec/rspec-mocks/docs – maxenglander 2012-08-02 22:03:09

+0

增加了更多信息。你绝对可以在rspec中使用mocks/stubs,就像@maxenglander指出的那样。 – 2012-08-02 22:04:48

相关问题