При написании функциональных тестов для контроллера я столкнулся со сценарием, в котором у меня есть before_filter, запрашивающий некоторую информацию из базы данных, которая требуется для одного из моих тестов. Я использую Factory_girl для генерации тестовых данных, но я хочу избежать попадания в базу данных, когда она явно не нужна. Я также хотел бы избежать тестирования моего метода before_filter здесь (я планирую проверить его в отдельном тесте). Как я понимаю, издевательство / окурки - это способ сделать это.
Мой вопрос заключается в том, как лучше всего смоделировать / заглушить этот метод в этом сценарии.
Метод My before filter ищет сайт в БД на основе субдомена, найденного в URL, и устанавливает переменную экземпляра для использования в контроллере:
#application_controller.rb
def load_site_from_subdomain
@site = Site.first(:conditions => { :subdomain => request.subdomain })
end
Мой контроллер, который использует этот метод в качестве before_filter:
# pages_controller.rb
before_filter :load_site_from_subdomain
def show
@page = @site.pages.find_by_id_or_slug(params[:id]).first
respond_to do |format|
format.html { render_themed_template }
format.xml { render :xml => @page }
end
end
Как видите, он зависит от переменной @site
, которую нужно установить (с помощью before_filter). Во время тестирования, однако, я хотел бы, чтобы тест предполагал, что @site
был установлен, и что у него есть по крайней мере 1 связанная страница (найденная @site.pages
). Затем я бы хотел проверить свой метод load_site_from_subdomain
.
Вот то, что у меня есть в моем тесте (с использованием Следует и Мокко):
context "a GET request to the #show action" do
setup do
@page = Factory(:page)
@site = Factory.build(:site)
# stub out the @page.site method so it doesn't go
# looking in the db for the site record, this is
# used in this test to add a subdomain to the URL
# when requesting the page
@page.stubs(:site).returns(@site)
# this is where I think I should stub the load_site_from_subdomain
# method, so the @site variable will still be set
# in the controller. I'm just not sure how to do that.
@controller.stubs(:load_site_from_subdomain).returns(@site)
@request.host = "#{ @page.site.subdomain }.example.com"
get :show, :id => @page.id
end
should assign_to(:site)
should assign_to(:page)
should respond_with(:success)
end
Это оставляет меня с ошибкой в моих результатах теста, говорящей мне, что @site
- ноль.
Я чувствую, что поступаю неправильно. Я знаю, что было бы просто просто создать Factory.создать сайт таким образом, чтобы он существовал в БД, но, как я сказал ранее, я хотел бы уменьшить использование БД, чтобы помочь ускорить мои тесты.