Тестирование вложенных ресурсов RSpec
-
22-09-2019 - |
Вопрос
У меня есть две модели:
class Solution < ActiveRecord::Base
belongs_to :owner, :class_name => "User", :foreign_key => :user_id
end
class User < ActiveRecord::Base
has_many :solutions
end
со следующей маршрутизацией:
map.resources :users, :has_many => :solutions
и вот SolutionsController:
class SolutionsController < ApplicationController
before_filter :load_user
def index
@solutions = @user.solutions
end
private
def load_user
@user = User.find(params[:user_id]) unless params[:user_id].nil?
end
end
Может ли кто-нибудь помочь мне написать тест для индексного действия?До сих пор я пробовал следующее, но это не работает:
describe SolutionsController do
before(:each) do
@user = Factory.create(:user)
@solutions = 7.times{Factory.build(:solution, :owner => @user)}
@user.stub!(:solutions).and_return(@solutions)
end
it "should find all of the solutions owned by a user" do
@user.should_receive(:solutions)
get :index, :user_id => @user.id
end
end
И я получаю следующую ошибку:
Spec::Mocks::MockExpectationError in 'SolutionsController GET index, when the user owns the software he is viewing should find all of the solutions owned by a user'
#<User:0x000000041c53e0> expected :solutions with (any args) once, but received it 0 times
Заранее спасибо за всю помощь.
Джо
РЕДАКТИРОВАТЬ:
Спасибо за ответ, я принял его, так как он продвинулся намного дальше, за исключением того, что я получаю еще одну ошибку, и я не могу понять, что он пытается мне сказать:
Как только я создаю решения вместо их сборки и добавляю заглушку User.find, я вижу следующую ошибку:
NoMethodError in 'SolutionsController GET index, when the user owns the software he is viewing should find all of the solutions owned by a user'
undefined method `find' for #<Class:0x000000027e3668>
Решение
Это потому, что вы создаете решение, а не создаете.Значит их нет в вашей базе данных.
Сделал
before(:each) do
@user = Factory.create(:user)
@solutions = 7.times{Factory.create(:solution, :owner => @user)}
@user.stub!(:solutions).and_return(@solutions)
end
И вы издеваетесь над экземпляром пользователя, но есть другой экземпляр пользователя, который можно создать.Вам также нужно добавить макет User.find
before(:each) do
@user = Factory.create(:user)
@solutions = 7.times{Factory.create(:solution, :owner => @user)}
User.stub!(:find).with(@user.id).and_return(@user)
@user.stub!(:solutions).and_return(@solutions)
end
Другие советы
Я разобрался со своим редактированием: когда поиск выполняется по параметрам, они представляют собой строки, а не реальные объекты или целые числа, поэтому вместо:
User.stub!(:find).with(@user.id).and_return(@user)
мне было нужно
User.stub!(:find).with(@user.id.to_s).and_return(@user)
но огромное спасибо, Шингара, ты направил меня в правильном направлении!
Джо