【发布时间】:2015-05-04 07:26:07
【问题描述】:
我对测试还很陌生,所以我一直在努力使用正确的语法,尤其是关于mocks。
我想在 cars_controller.rb
中测试我的destroy 操作
def destroy
if current_user.cars.exists?(params[:id])
car = current_user.cars.find(params[:id])
# only destroy the car if it has no bookings
car.destroy unless car.bookings.exists?
end
redirect_to user_cars_path(current_user)
end
当没有与汽车相关的预订时,测试案例相当容易。
describe CarsController, type: :controller do
let(:user) { create(:user_with_car) }
before { login_user(user) }
describe "DELETE #destroy" do
let(:car) { user.cars.first }
context "when the car has no bookings associated to it" do
it "destroys the requested car" do
expect {
delete :destroy, user_id: user.id, id: car.id
}.to change(user.cars, :count).by(-1)
end
end
但是这个测试让我发疯了:
context "when the car has bookings associated to it" do
it "does not destroy the requested car" do
##### This line fails miserably
allow(car).to receive_message_chain(:bookings) { [ Booking.new ]}
expect {
delete :destroy, user_id: user.id, id: car.id
}.to change(user.cars, :count).by(0)
end
end
end
end
我不想在数据库中创建预订并将它们与汽车相关联。据我了解,建议模拟这些预订,因为它们没有用处。
旁边:
allow(car).to receive_message_chain(:bookings) { [ Booking.new ]}
我已经多次尝试使用其他语法',但都失败了。我什至尝试使用 rpsec-mocks 旧语法:stub(...)。
我将如何做到这一点?
【问题讨论】:
-
除非您确实有消息链,否则您可能不需要接收消息链。这里只有一个,所以你应该可以这样做:
allow(car).to receive(:bookings) { [ Booking.new ]}? -
另外,我不知道为什么会阻塞。怎么样:
allow(car).to receive(:bookings).and_return([ Booking.new])因为它更明确
标签: ruby-on-rails activerecord rspec mocking