ruby – 将类/模块恢复到处女状态
我想知道RSpec如何实现这个目标:
expect( MyObject ).to receive(:the_answer).and_return(42) RSpec是否利用define_singleton_method将the_answer注入MyObject? 那可能有用.让我们假装这是MyObject的样子: class MyObject def self.the_answer 21 * 2 end end 注入的the_answer方法可能包含以下内容: @the_answer_called = true 42 然而,RSpec如何将类恢复到其未冻结状态?它如何恢复它以便MyObject.the_answer“真正”再次返回42? (通过21 * 2) 自写这个问题以来,我认为它没有.在RSpec停止运行之前,类方法仍然被模拟. 然而,(这是问题的关键)如何撤消define_singleton_method? 我认为最简单的方法是在使用define_singleton_method之前运行old_object = Object.dup,但是,如何将old_object恢复为Object? 当我想要做的就是恢复一个类方法时,这也不会让我觉得有效.虽然目前这不是一个问题,但也许将来我也希望将MyObject中的某些实例变量保持不变.是否有一种非hacky方式复制代码(21 * 2)并通过define_singleton_method重新定义为the_answer而不是完全替换Object? 欢迎所有想法,我绝对想知道如何制作Object === old_object. 解决方法
RSpec不会复制/替换实例或其类.它动态删除实例方法并定义一个新方法.以下是它的工作原理:(你可以对类方法做同样的事情)
给定您的类MyObject和一个实例o: class MyObject def the_answer 21 * 2 end end o = MyObject.new o.the_answer #=> 42 RSpec首先使用 original_method = MyObject.instance_method(:the_answer) #=> #<UnboundMethod: MyObject#the_answer> 然后它使用 MyObject.send(:remove_method,:the_answer) 并使用 MyObject.send(:define_method,:the_answer) { 'foo' } 如果您现在调用the_answer,则会立即调用新方法: o.the_answer #=> "foo" 在示例之后,RSpec删除了新方法 MyObject.send(:remove_method,:the_answer) 并恢复原始的(define_method接受块或方法): MyObject.send(:define_method,:the_answer,original_method) 调用方法按预期工作: o.the_answer #=> 42 RSpec的实际代码要复杂得多,但你明白了. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- ruby-on-rails – 在Rails中安装Rack应用程序不起作用
- ruby – 安装nokogiri错误:无法识别的命令行选项“-Wdivis
- Confluence 6 重新获得站点备份文件
- 使用Ruby on Rails快速开发web应用的教程实例
- oracle – 如何在条件下找到两行之间的差异
- ruby-on-rails – Paperclip | ImageMagick – 无法使用自定
- ruby-on-rails – Rails – 使用外部SOAP API的最佳方式?
- 使用SQLite数据库存储数据
- C++中对C语言结构体用法的扩充
- React-Redux技术栈——之redux-form详解