我测试我的应用程序是否创建了一个新的用户汽车,之后用户创建新车,应用程序必须重定向到user_car_path(我发布我的路线):
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
所以我用这个rspec测试我的应用程序:
describe "POST 'create' car" do
describe "car created 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 cars page" do
post :create, :cars => @car, :user_id => @user.id
response.should redirect_to user_car_path(@user, @car)
end
end
end
但我有2个错误
Failures:
1) CarsController POST 'create' car car created success should create a car
Failure/Error: lambda do
count should have been changed by 1, but was changed by 0
# ./spec/controllers/car_controller_spec.rb:20
2) CarsController POST 'create' car car created success should redirect to the user cars page
Failure/Error: response.should redirect_to user_car_path(@user, @car)
Expected response to be a redirect to <http://test.host/users/115/cars/40> but was a redirect to <http://test.host/users/115/cars/new>.
# ./spec/controllers/car_controller_spec.rb:27
但我的应用程序正常工作;这是我的CarController
class CarsController < ApplicationController
....
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
def show
@user = User.find(params[:user_id])
@car = @user.cars.find(params[:id])
end
....
答案 0 :(得分:4)
您正在数据库中创建汽车,而不是仅在before(:each)
中创建汽车对象。你也把这个参数传递给:cars
而不是:car
。最后,我还要亲自使用let
。试试这个。
describe "POST 'create' car" do
let(:user) { User.create!(:email => "foo@example.com", :password => "foobar", :password_confirmation => "foobar" ) }
let(:car) { Car.new(:brand => "example", :color => "foobar", :model => "foobar", :year =>"2012")}
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 cars page" do
post :create, :cars => car, :user_id => user.id
# note: car doesn't have an ID, you have to fetch it from the db to get an id
response.should redirect_to user_car_path(user.id, user.cars.last.id)
end
end
最后请注意,您需要查看Factory Girl
然后你可以这样做:
let(:user){ FactoryGirl.create(:user) }
let(:car) { FactoryGirl.build(:car) } # note: BUILD not CREATE
答案 1 :(得分:0)
我认为你想要以下(:cars =&gt;:car并使用params,这将使控制器中的汽车创建有效。我很困惑为什么你在你的规范中创建汽车因为这似乎是一个测试汽车创造)
it "should create a car" do
lambda do
post :create, :car => {:brand => "example", :color => "foobar", :model => "foobar", :year =>"2012"}, :user_id => @user.id
end.should change(Car, :count).by(1)
end
it "should redirect to the user cars page" do
post :create, :car => {:brand => "example", :color => "foobar", :model => "foobar", :year =>"2012"}, :user_id => @user.id
response.should redirect_to user_car_path(@user, @car)
end
答案 2 :(得分:0)
我认为这是因为您的验证失败了。要知道它是否失败,请在保存到控制器之前执行此操作:
puts @car.valid?
如果它是假的,你的测试将失败,这是正常的。要设置为true,您可以执行以下操作:
before(:each) do
...
Car.any_instance.stub(:valid?).and_return(true)
end
您还可以使用存根和模拟来返回User.find
和Car.build
的实例。请参阅文档:https://www.relishapp.com/rspec/rspec-mocks/v/2-6/docs/method-stubs