Ruby:模拟本地对象来测试模块方法

标签 ruby testing rspec module sinatra

在 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/

相关文章:

ruby-on-rails - 如果 gsub 的替换值为 null,我怎么能有默认值?

arrays - 选择方法等同于仅在 Ruby 中保留索引

unit-testing - 单元测试新手,如何编写出色的测试?

ruby - 在 Jenkins 上运行时找不到 gem rspec-core (>= 0.a) (Gem::GemNotFoundException)

ruby-on-rails - 在 Rails 中,我从 Guard 那里收到这个错误,说我必须更新到新的 :cmd syntax

ruby-on-rails - 如何将特定的 ruby​​ gem 升级到特定(或最新)版本?

ruby - rvm:找不到命令(Fedora 12)

java - 您如何测试通用 API 的类型安全性?

c++ - 从 ASSERT_THROW 获取异常信息

ruby - 如何创建一个将散列(有或没有指定值)作为参数的方法?