在 Sinatra 中工作时,会创建一个本地对象 request
并将其提供给所有 View 和助手。因此,我可以使用辅助方法创建一个 ApplicationHelper
模块,如果在 View 中调用辅助方法,它们可以依次调用 request
对象,如下所示:
module ApplicationHelper
def nav_link_to(text,path)
path == request.path_info ? klass = 'class="current"' : klass = ''
%Q|<a href="#{path}" #{klass}>#{text}</a>|
end
end
现在,我想对此进行测试,但在我的测试中,request
对象不存在。我试图 mock 它,但这没有用。这是我到目前为止的测试:
require 'minitest_helper'
require 'helpers/application_helper'
describe ApplicationHelper do
before :all do
@helper = Object.new
@helper.extend(ApplicationHelper)
end
describe "nav links" do
before :each do
request = MiniTest::Mock.new
request.expect :path_info, '/'
end
it "should return a link to a path" do
@helper.nav_link_to('test','/test').must_equal '<a href="/test">test</a>'
end
it "should return an anchor link to the current path with class 'current'" do
@helper.nav_link_to('test','/').must_equal '<a href="test" class="current">test</a>'
end
end
end
那么,如何模拟“本地”对象以便您的测试代码可以调用它?
最佳答案
您需要确保您的 @helper
对象上有一个 request
方法,该方法返回模拟请求对象。
在 RSpec 中我只是 stub 它。我对 Minitest 不是特别熟悉,但快速浏览一下表明这可能在最近的版本中起作用(如果您在 before 中将
):request
更改为 @request
:每个
it "should return a link to a path" do
@helper.stub :request, @request do
@helper.nav_link_to('test','/test').must_equal '<a href="/test">test</a>'
end
end
更新
由于 Minitest 要求已在对象上定义 stub 方法,因此您可以将 @helper
设为 Struct.new(:request)
的实例,而不是 对象
,即
@helper = Struct.new(:request).new
实际上,完成此操作后,您可能根本不需要 stub !你可以这样做
before :each do
@helper.request = MiniTest::Mock.new
@helper.request.expect :path_info, '/'
end
关于Ruby:模拟本地对象来测试模块方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13734983/