惩戒/打桩的应用控制器方法与摩卡(使用早该,Rails的3)
-
27-09-2019 - |
题
在写功能测试的控制器,我碰到一种情况,我有一个请求的before_filter从数据库中一些信息,我的测试一个要求。我使用Factory_girl生成测试数据,但我想避免进入数据库的不明确需要的时候。我也想避免在这里测试我的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.create的网站,以便它在数据库中存在,但正如我刚才所说,我想分贝的使用减少,以帮助保持我的测试迅速。
解决方案
尝试删空“Site.first”,因为它的@site VAR的设置,你需要存根,而不是从的before_filter返回的变种。
其他提示
之所以你@site
是nil
因为你load_site_from_subdomain
确实为@site
的赋值 - 它不返回任何值,因此您的load_site_from_subdomain
磕碰根本不分配值@site
。有两种解决此:
<强>首先方式:强>
更改load_site_from_subdomain
只是做一个返回值:
def load_site_from_subdomain
Site.first(:conditions => { :subdomain => request.subdomain })
end
,然后取下before_filter :load_site_from_subdomain
和更改show
为:
def show
@site = load_site_from_subdomain
@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
和然后执行在测试中磕碰:
@controller.stubs(:load_site_from_subdomain).returns(@site)
这确保我们@site
间接地经由load_site_from_subdomain
<强>方式二强>
要存根Site.first
,我真的不喜欢这种方法,如功能测试,我们并不真正关心的模型如何检索但respond
的行为。无论如何,如果你想去这条道路,你可以在你的测试存根出来:
Site.stubs(:first).returns(@site)