从 TestCase 调用 Sinatra 应用实例方法 [英] Calling a Sinatra app instance method from TestCase

查看:37
本文介绍了从 TestCase 调用 Sinatra 应用实例方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an util method into a Sinatra application and I would like to tested from my TestCase.

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

The problem is that I don't know how to invoke it, if I just use app.util_method I have the error NameError: undefined local variable or method 'util_method' for #<Sinatra::ExtendedRack:0x007fc0c43305b8>

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

推荐答案

Sinatra 在重新定义它之前将 new 方法别名为 new!,所以最简单的解决方案是使用它:

Sinatra aliases the new method to new! before redefining it, so the simplest solution is to use that instead:

def app
  MyApp.new!
end

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

Of course I only noticed that after I’d come up with the following, which I’ll leave in as it could be useful/informative.

绕过 Sinatra 的可能方法 重新定义 new 方法并返回一个完整的 Rack 应用程序 获取一个实例,你的实际基类是做真正的"new 方法自己做的:

A possible way to get round Sinatra redefining the new method and returning a complete Rack app a get hold of an instance your actual base class is to do what the "real" new method does yourself:

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

这有点小技巧,但它可能对测试有用.

This is a bit of a hack, but it might be useful for testing.

另一种技术是走"中间件堆栈,直到你到达你的班级.下面的代码有点脆弱,因为它依赖于使用名称 @app 来引用堆栈中的下一个应用程序所涉及的所有中间件,但这很常见.

Another technique would be to "walk" the middleware stack until you got to your class. The following is a little fragile, as it depends on all the middleware involved to use the name @app to refer to the next app in the stack, but this is fairly common.

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

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

That won’t work on the yet to be released Sinatra 1.4 though (at least not on the current master, which is commit 41840746e866e8e8e9a0eaafc53d8b9fe6615b12), as new now returns a Wrapper class and the loop never ends. In this case you can grab the base class directly from the @instance variable:

def app
  MyApp.new.instance_variable_get :@instance
end

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

(note this last technique may well change before the final 1.4 release).

这篇关于从 TestCase 调用 Sinatra 应用实例方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆