#unit-testing #ruby-on-rails-3 #rspec #mongoid #rspec2
#модульное тестирование #ruby-on-rails-3 #rspec #mongoid #rspec2
Вопрос:
Я пытаюсь написать свои первые спецификации для контроллера People, используя mongoid (2.0.1), rspec (2.5.0), mongoid-rspec (1.4.2) и fabrication (0.9.5), если необходимо.
(примечание: модель организации, над которой издевались, наследуется от модели Person)
describe PeopleController do
describe "as logged in user" do
before (:each) do
@user = Fabricate(:user)
sign_in @user
end
describe "GET 'index'" do
def mock_person(stubs={})
@mock_person ||= mock_model(Person, stubs).as_null_object
# @mock_person ||= Fabricate.build(:organization)
end
it "should be successful" do
get :index
response.should be_success
end
it "assigns all people as @people" do
Person.stub(:all) { [mock_person] }
get :index
assigns(:people).should eq(mock_person)
end
end
end
При запуске этой спецификации я получаю следующее сообщение об ошибке:
1) PeopleController as logged in user GET 'index' assigns all people as @people
Failure/Error: assigns(:people).should eq(mock_person)
expected #<Person:0x811b8448 @name="Person_1001">
got #<Mongoid::Criteria
selector: {},
options: {},
class: Person,
embedded: false>
(compared using ==)
Diff:
@@ -1,2 1,6 @@
-#<Person:0x811b8448 @name="Person_1001">
#<Mongoid::Criteria
selector: {},
options: {},
class: Person,
embedded: false>
# ./spec/controllers/people_controller_spec.rb:24:in `block (4 levels) in <top (required)>'
Мой контроллер НЕ работает благодаря inherited_resources (1.2.2) и работает в режиме разработки, как и должно быть.
class PeopleController < InheritedResources::Base
actions :index
end
Есть идеи, что я делаю неправильно Mongoid::Criteria
с объектом?
Заранее спасибо
Ответ №1:
У меня была такая же проблема, но после объединения mongoid-rspec проблема исчезла!
Комментарии:
1. Как вы адаптировались
mongoid-rspec
к тестам контроллера? Я используюmongoid-rspec
в моделях… Можете ли вы рассказать мне, как вы добавилиmongoid-rspec
в свой контроллер?. Спасибо!
Ответ №2:
К сожалению, у меня такая же проблема, и единственное решение, которое я смог придумать, — это поместить это в контроллер:
def index
@people = Person.all.to_a
end
to_a
Метод преобразует Mongoid::Criteria
объект в массив. Этот способ работает для меня, но я не знаю, как вы могли бы это сделать, используя inherited_resources.
Ответ №3:
Лично я отказался от тестирования действий с индексом inherited_resources с заглушкой и тестирования возвращенных критериев:
describe "GET 'index'" do
before do
get 'index'
end
it "returns http success" do
response.should be_success
end
it "should have news" do
assigns[:news].should be_a(Mongoid::Criteria)
assigns[:news].selector.should == {}
assigns[:news].klass.should == News
assigns[:news].options[:sort].should == [[:created_at, :desc]]
assigns[:news].options[:limit].should == 10
end
end
Ответ №4:
Недавно я столкнулся с аналогичной проблемой, когда мой контроллер возвращает, как ожидалось, но присваивает (: темы) в моем rspec сбой (возвращено больше фактических элементов).
По сути, это связано с тем, что назначаемые rspec не могут загрузить фактический ресурс коллекции, полученный через унаследованные ресурсы.
Для обхода я использовал его для принудительной загрузки назначений (: topics) с помощью logger.info:
class TopicsController < InheritedResources::Base
def index
# Needed for rspec assigns() to pass,
# since it doesn't evalue inherited_resources resource assignment
logger.info "Topics: #{@topics.inspect}" if Rails.env.test?
end
end
Надеюсь, это поможет.