Ruby:在代码块中更改类静态方法

2024-03-21

给定 Thread 类及其当前方法。 现在在测试中,我想这样做:

def test_alter_current_thread
  Thread.current = a_stubbed_method
  # do something that involve the work of Thread.current
  Thread.current = default_thread_current
end

基本上,我想改变测试方法中的类的方法,然后恢复它。 我知道这对于另一种语言来说听起来很复杂,比如 Java 和 C#(在 Java 中,只有强大的模拟框架才能做到)。但这是红宝石,我希望如此nasty东西会可用


您可能想看看 Ruby 模拟框架,例如Mocha http://mocha.rubyforge.org/,但就使用普通 Ruby 而言,可以使用alias_method(文档here http://ruby-doc.org/core/classes/Module.html#M001653) e.g.

预先:

class Thread
  class << self
    alias_method :old_current, :current
  end
end

然后定义你的新方法

class Thread
  def self.current
    # implementation here
  end
end

然后恢复旧方法:

class Thread
  class << self
    alias_method :current, :old_current
  end
end

更新以说明在测试中执行此操作

如果您想在测试中执行此操作,您可以定义一些辅助方法,如下所示:

def replace_class_method(cls, meth, new_impl)
  cls.class_eval("class << self; alias_method :old_#{meth}, :#{meth}; end")
  cls.class_eval(new_impl)
end

def restore_class_method(cls, meth)
  cls.class_eval("class << self; alias_method :#{meth}, :old_#{meth}; end")
end

replace_class_method需要一个类常量、一个类方法的名称和一个字符串形式的新方法定义。restore_class_method获取类和方法名称,然后将原始方法别名放回原位。

然后您的测试将类似于:

def test
  new_impl = <<EOM
  def self.current
    "replaced!"
  end
EOM
  replace_class_method(Thread, 'current', s)
  puts "Replaced method call: #{Thread.current}"
  restore_class_method(Thread, 'current')
  puts "Restored method call: #{Thread.current}"
end

您还可以编写一个小包装方法,该方法将替换一个方法,产生一个块,然后确保随后恢复原始方法,例如

def with_replaced_method(cls, meth, new_impl)
    replace_class_method(cls, meth, new_impl)
    begin
        result = yield
    ensure
        restore_class_method(cls, meth)
    end
    return result
end

在您的测试方法中,这可以用作:

with_replaced_method(Thread, 'current', new_impl) do
  # test code using the replaced method goes here
end
# after this point the original method definition is restored

正如原始答案中提到的,您可能可以找到一个框架来为您执行此操作,但希望上面的代码无论如何都是有趣且有用的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Ruby:在代码块中更改类静态方法 的相关文章

  • Guard 不会加载 WDM

    我正在学习 Michael Hartl 的 Rails 教程 到目前为止该教程非常出色 我在高级设置一章中 他以有利于 TDD 的方式配置 Rails 环境 我安装了 Guard 并且通过运行我在 spec 文件夹中的测试 它一直正常运行
  • 查询参数和assert_generates/assert_routing - 我缺少什么?

    我想我已经介绍了使用查询参数测试路由的排列 但没有一种方法通过 在我的 paths rb 中 我有以下内容 resources items 然后对于我的功能测试我有 require ruby debug require test helpe
  • 尝试使用 Rails 和 PostgreSQL 生成模型时,命令挂起且没有错误

    使用该命令时 rails generate model Event name string 什么也没发生 我必须按 CTRL c 我使用的版本是 红宝石 2 1 1p76 导轨4 1 0 PostgreSQL 9 3 4 Mac OS X
  • 防止语言环境文件中的 HTML 字符实体被 Rails3 xss 保护破坏

    我们正在构建一个应用程序 这是我们第一个使用 Rails 3 的应用程序 并且我们必须从一开始就构建 I18n 作为完美主义者 我们希望在我们的视图中使用真正的排版 破折号 卷曲引号 省略号等 这意味着在我们的 locales xx yml
  • NoMethodError 未定义方法“名称” for nil:NilClass

    我有两个模型帖子和类别 我试图在我的索引和帖子显示视图中显示每个帖子的类别名称 我正在使用表连接 但问题是 虽然在我的显示视图中类别显示正确 但它在索引视图中给出了 NoMethodError undefined method name f
  • 如何在 Ruby on Rails 3 中使用 Active Record 搜索文本?

    如何在 Ruby on Rails 中搜索字符串 例如 列包含 文本 的所有记录 Active Record 有方法吗 还是我必须使用 SQL LIKE Model find all conditions gt name LIKE tag
  • C# 模拟接口与模拟类

    我是 net 中的最小起订量框架的新手 根据我的在线研究 似乎有两种方法可以使用这个框架 要么模拟接口 要么模拟具体类 似乎在嘲笑具体类时 只有virtual方法可以被嘲笑 就我而言 我只想模拟实现接口的类的几个方法 例如 如果我们有以下内
  • Rails 3 默认作用域、可覆盖的作用域

    我遇到的情况是现有应用程序的行为正在发生变化 这让我非常头疼 我的应用程序有照片 照片有一个状态 batch queue or complete 应用程序中的所有现有照片都是 完整的 99 的情况下 我只需要显示完整的照片 并且在所有现有代
  • Bootstrap shown.bs.tab 事件不起作用

    我正在使用灵活的模板 http the8guild com themes html flexy v1 7 stylesPage html 使用引导程序 并且我无法让选项卡上的 shown bs tab 事件正常工作 我已经成功让它发挥作用J
  • 同一模型之间的两个 has_many 链接

    I have users其中有products通过 habtm 链接 该链接正在运行 我想添加一个链接user模型和product模型 以跟踪creator该产品的 当然 谁并不总是拥有该产品 但是当我写在我的user and produc
  • 如何从模型调用辅助方法?

    我使用 MongoDB 作为我的 Rails 应用程序中的数据库和 MongoID gem 我想从模型中调用辅助方法after create回调方法 这怎么可能 我的模型代码是 class Department include Applic
  • 我们能否知道回形针下载何时完成?

    我有一个应用程序 我需要知道用户的 Rails Paperclip 文件下载时间complete 我的应用程序设置为与 Amazon S3 交互 当用户收到完整的文件时 我需要运行 JavaScript 函数 我怎样才能做到这一点 跟踪天气
  • Rails 4 - 如何链接到 PDF 文件(名称.PDF)?

    我正在生成 PDF 文件 我的链接如下所示 当我点击这个时 它会带我去 display invoice 123456789 这是一个 HTML 版本 在控制器中的操作如下 def display invoice if params invo
  • Rails:format.js 或 format.json,或两者?

    可能很明显 但我仍然缺乏基本知识 那么在控制器内部 两者都可以使用 还是总是 Javascript 所以两者是相同的 json and js是两种不同类型的响应 它们在 Rails 中被定义为不同的 MIME 类型 Mime Type re
  • Python:使类可迭代

    我继承了一个包含许多大型类的项目 这些类仅由类对象 整数 字符串等 组成 我希望能够检查属性是否存在 而无需手动定义属性列表 是否可以制作一条蟒蛇classiterable 本身使用标准语法 也就是说 我希望能够使用迭代所有类的属性for
  • 为什么“捆绑”会在我的开发机器上安装生产 gem?

    Gemfile 说 gem sqlite3 groups gt development test gem mysql2 group gt production 然而当我打字时bundle install在我的开发机器上安装了所有 gem 我
  • 在rails中,如何将记录作为csv文件返回

    我有一个名为 Entries 的简单数据库表 class CreateEntries lt ActiveRecord Migration def self up create table entries do t t string firs
  • 创建一个简单的 Rails 3 文本助手 Gem [重复]

    这个问题在这里已经有答案了 我一直在开发我的第一个 Rails 3 插件 以打包一个我喜欢在ApplicationHelper我所有的应用程序 你可以看到整个代码在 Github 上 https github com burlesona s
  • 将 Rails 变量传递给液体可以在控制台中工作,但不在视图中

    我想将哈希传递给渲染方法 当我这样做时 在我的控制台中一切正常 object Object find params id hash object object to liquid template Liquid Template parse
  • Rails 3 + angularjs + 缩小在生产中不起作用:未知提供者:eProvider

    我已遵循我能找到的所有修复缩小的说明 例如 var MyController function renamed scope renamedGreeter MyController inject scope greeter and someM

随机推荐

  • 使用 Sprite Kit 创建水(流体)表面[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我怎样才能创建水面精灵套件 我已经搜索并找到了帮助Cocos2d它使用box2d为水创建物理效果 例如漂浮在水面上的物体以及其部分在水
  • 在 PowerShell 中运行 CMD 命令

    我在运行 PowerShell 命令时遇到了很多问题 它所做的只是运行一个在 CMD 提示窗口中运行的命令 这是命令 C Program Files x86 Microsoft Configuration Manager AdminCons
  • MongoDB 线程安全吗?

    我在 Windows 上运行 MongoDB 我有 1 个或多个线程删除并重新创建集合 Using mongo exe与show collections 命令 我看到多个具有相同名称的集合 远远超过 1 000 个具有相同名称的集合 当我运
  • 什么是 href="#" 以及为什么使用它?

    在许多网站上我看到链接href 这是什么意思 它是干什么用的 关于超链接 锚标签的主要用途 a a 是作为超链接 http www w3 org MarkUp html spec html spec 7 html 这基本上意味着他们会带你去
  • 如何在没有 equals/hashcode 的情况下删除 List 中的重复对象?

    我必须删除列表中重复的对象 它是来自博客对象的列表 如下所示 public class Blog private String title private String author private String url private S
  • 从 numpy 数组转换为 RGB 图像

    我有三个 241 241 numpy 数组 我想将它们视为图像的红色 绿色和蓝色分量 我已经尝试过这个 import numpy as np from PIL import Image arr np zeros len x len z 3
  • GWT 模块可能需要(重新)编译 REDUX

    在编译模式下运行时 我收到这个可怕的 GWT Module mymodule may need to be re compiled 对话框消息 我已经编制了一份其他人建议在编译模式下运行的 GWT 给出此错误消息时建议尝试的操作列表 我已经
  • 如何将变量传递给 MySQL LIMIT 子句?

    我正在尝试使用 pymysql 对 Mysql 数据库执行 SELECT 语句 这是代码 我将一个变量传递给 select 语句 令我惊讶的是 这是一个巨大的痛苦 知道我在这里缺少什么吗 def getUrlFromDatabase n s
  • 无法删除 MemoryMappedFile 的文件

    以下代码抛出此异常 该进程无法访问文件 filename 因为它正在被另一个进程使用 很公平 但是关闭阅读器和 或 mmf 以便删除文件的正确方法是什么 我认为 MemoryMappedFile 会有一个 close 方法或类似的方法 但事
  • onHashChange 在 Safari 中工作吗?

    Does onHashChange or hashChange在 Safari 中工作 我在 Windows 7 上使用 Safari 4 0 4 进行了测试 但它对我不起作用 如果不起作用 是否有任何解决方案可以跟踪hash已经改变 在我
  • 如何在黑莓中创建选项卡栏应用程序用户界面...?

    如何在 BB 中制作选项卡栏基础应用程序 应用程序的每个屏幕都将有此选项卡 并且每个选项卡将有单独的导航控制器堆栈 以便我们可以轻松地推送屏幕 您必须使用水平字段管理器创建选项卡栏 然后将字段添加到水平字段管理器 然后将管理器设置为屏幕的标
  • 将 DataGrid 列标题居中对齐

    我需要对齐WPF DataGrid Column Header发短信至Center 我创建了一个样式并使用HeaderStyle属性如下 Style
  • Log4Net 不工作

    我正在 Windows XP 中以管理员用户身份使用 C 开发 NET Framework 3 5 并使用 log4net 进行 NET Framework 2 0 二进制引用 我曾尝试过log4net 缺少什么 未创建日志文件 https
  • TCPDF:HTML 表格和分页符

    I am creating a large HTML table and I have problem with page breaks as you can see in the following image Is there a me
  • 获取准确的窗口区域大小 - CreateWindow 窗口大小不是正确的窗口大小

    在尝试用 C 创建窗口并绘制窗口大小与我设置的大小不匹配的矩形时 我注意到一些非常烦人的事情 例如 如果我设置 480x240 窗口并尝试通过获取 GetWindowRect hwnd rect 从上到下 从左到右绘制矩形并计算宽度和高度
  • jQuery Post blob 对象给出 Uncaught TypeError:非法调用

    我正在尝试使用 jQuery 发布文件post 并得到TypeError Illegal invocation function fbUpload token var dataURL canvas toDataURL image jpeg
  • 我的 java 程序正在运行编译但没有显示任何内容

    package myproj import java sql Connection import java sql DriverManager import java sql PreparedStatement import java sq
  • 使用 Javascript 检查测验答案的最安全方法

    在努力完成一个使用 AJAX PHP 设计匹配问答游戏的项目后 我了解到我公司用于分发其产品的学习套件不允许我在后端运行服务器端脚本来安全地检查答案 这都是由于不幸的等级专制造成的 长话短说 我必须以某种方式检查客户端的答案 或找出一些棘手
  • 使用 DinkToPdf 分隔分页符

    我的 Program cs 中有这个 C var page plain var slnpath Directory GetCurrentDirectory var htmlpath slnpath HtmlTemplates page ht
  • Ruby:在代码块中更改类静态方法

    给定 Thread 类及其当前方法 现在在测试中 我想这样做 def test alter current thread Thread current a stubbed method do something that involve t