ruby - 从 TestCase 调用 Sinatra 应用程序实例方法

标签 ruby sinatra rack

我在 Sinatra 应用程序中有一个 util 方法,我想从我的 TestCase 进行测试.

问题是我不知道如何调用它,如果我只使用 app.util_method我有错误 NameError: undefined local variable or method 'util_method' for #<Sinatra::ExtendedRack:0x007fc0c43305b8>

我的应用.rb:

class MyApp < Sinatra::Base
  # [...] routes methods

  # utils methods
  def util_method
    return "hi"
  end
end

my_app_test.rb:

require "my_app.rb"
require "test/unit"
require "rack/test"

class MyAppTest < Test::Unit::TestCase
  include Rack::Test::Methods

  def app
    MyApp.new
  end

  # [...] routes methods tests

  def test_util_method
    assert_equal( "hi", app.util_method )
  end
end

最佳答案

西纳特拉 aliases the new method to new!在重新定义它之前,所以最简单的解决方案是改用它:

def app
  MyApp.new!
end

当然,我只是注意到之后我想出了以下内容,我将保留这些内容,因为它可能有用/提供信息。


绕过 Sinatra 的可能方法 redefining the new method and returning a complete Rack app获取一个实例,您的实际基类将执行“真正的”new 方法自己执行的操作:

def app
  a = MyApp.allocate
  a.send :initialize
  a
end

这有点 hack,但它可能对测试有用。

另一种技术是“遍历”中间件堆栈,直到您到达您的类(class)。以下内容有点脆弱,因为它依赖于所有涉及的中间件使用名称 @app 来引用堆栈中的下一个应用程序,但这很常见。

def app
  a = MyApp.new
  while a.class != MyApp
    a = a.instance_variable_get(:@app)
  end
  a
end

不过,这在尚未发布的 Sinatra 1.4 上不起作用(至少在当前的 master,即 commit 41840746e866e8e8e9a0eaafc53d8b9fe6615b12 上不起作用),因为 new 现在返回一个 Wrapper class循环永远不会结束。在这种情况下,您可以直接从 @instance 变量中获取基类:

def app
  MyApp.new.instance_variable_get :@instance
end

(请注意,最后一项技术可能会在最终 1.4 版本发布之前发生变化)。

关于ruby - 从 TestCase 调用 Sinatra 应用程序实例方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12072865/

相关文章:

ruby - 如何根据数组中对象的两个属性创建哈希?

ruby-on-rails - 用作回调时, `return` 和 `break` 在 Ruby block 中是否无用?

Ruby 和 Linux,首选设置?

javascript - 从第三方网站的 script/include 标签配置 Javascript 的最佳方法是什么?

ruby - 西纳特拉静态页面

ruby - Sinatra/Rack 因 url 中的非 ascii 字符而失败

Ruby/Grape 在特定条件下需要参数

mysql - Ruby:Sequel gem 插入到 Mysql

ruby - 使用 Ruby 发送自定义 HTTP header

ruby - 如何为 Rack 静态站点编写 config.ru?