回答
看看http://blog.ardes.com/2006/12/11/testing-singletons-with-ruby:“全局变量是坏,m'kay”
require 'singleton'
class <<Singleton
def included_with_reset(klass)
included_without_reset(klass)
class <<klass
def reset_instance
Singleton.send :__init__, self
self
end
end
end
alias_method :included_without_reset, :included
alias_method :included, :included_with_reset
end
RSpec是否允许您执行预测试操作?是这样的,你可以添加另一个方法给你静态类,在构造函数中清除所有的东西。然后在每个测试之前调用它。
RSpec具有“之前”和“之后”的块。 http://rspec.info/documentation/before_and_after.html – 2009-12-15 17:58:01
但是由于Singleton模式,构造函数不会被调用两次。 – brainfck 2009-12-15 17:59:56
将它重构为可以多次构建的类。这具有从类中去除Singleton特性的副作用(有些人会说是好处)。
再看另一种方式:您已经发现需要多次调用构造函数。为什么应该该类只构造一个实例?辛格尔顿提供什么好处?
构造函数不需要多次调用,但我想保持我的规格清晰 - 所以我只测试每个规范中构造函数的一部分。 – brainfck 2009-12-15 17:59:20
您可以简单地制作一个新的it
并为每个规格块。将你的规格分解成可测试的单元。使用“之前”和“之后”来设置和清除你所做的任何事情。
before(:each)
和after(:each)
每隔it
块被执行。
原因之一的人使用,因为单身单例是一个全局变量,被隔离在一个名字空间中,并且具有懒惰的实例化。考虑一个真正的全局变量是否可以简化事情,特别是如果你不需要延迟实例化。
我见过的一种模式是将单例作为真实类的一个子类。您在生产代码中使用Singleton版本,但在测试中使用基础(非单例)类。
例子:
class MyClass
attr_accessor :some_state
def initialize
@some_state = {}
end
end
class MySingletonClass < MyClass
include Singleton
end
...但我在寻找一个更好的办法喽。
我的问题的一部分是我使用JRuby并挂接到Java系统首选项,其中是全局的。其余的我认为我可以重构。
# singleton_spec.rb
require "singleton"
class Global
include Singleton
def initialize
puts "Initializing"
end
end
describe Global do
before do
Singleton.__init__(Global)
end
it "test1" do
Global.instance
end
it "test2" do
Global.instance
end
end
% rspec singleton_spec.rb -fd
Global
Initializing
test1
Initializing
test2
关键是“Singleton .__ init __(Global)”。那钉为我。谢谢。 – iHiD 2013-10-20 00:22:46
问题是,这会重置单身人士。如果您的应用的任何其他部分依赖于先前设置的全局状态,则会中断。例如,如果您使用的是注册表模式,那么如何测试注册表而不破坏使用注册表的组件的测试? – 2014-05-28 01:44:46
辛格尔顿类基本上做到这一点
def self.instance
@instance ||= new
end
private_class_method :new
所以,你可以通过调用使用发送
let(:instance) { GlobalClass.send(:new) }
的这样一个很好的好处是,没有新的私有方法完全绕过记忆化全局状态会因您的测试运行而被修改。
可能是一个更好的办法,从this answer:
let(:instance) { Class.new(GlobalClass).instance }
这将创建一个匿名类从GlobalClass
继承,所有类级别的实例变量都存储在这则每个后扔掉。测试,保持GlobalClass
不变。
这是一个简单直接的解决方案。 – 2014-05-28 02:24:45
谢谢,这是非常有帮助的。 – chrisco 2015-09-13 12:41:17
- 1. 如何测试PHP PDO Singleton类?
- 2. 如何用DUnit测试Singleton类?
- 3. 使用Singleton进行单元测试
- 4. Java:注入Singleton bean来测试
- 5. Singleton类
- 6. 如何编写测试类
- 7. 如何测试容器类?
- 8. 如何为类中的所有测试设置测试类别
- 9. 如果类本身正在使用PowerMock进行测试,如何模拟Singleton类的私有方法?
- 10. 如何测试类和她的子类
- 11. 如何忽略测试类类与ArchUnit
- 12. Singleton DAL类
- 13. Singleton类崩溃
- 14. Singleton类Flex中
- 15. 如何测试junit测试
- 16. 如何从第一类(APEX类测试/ salesforce测试)中测试第二类func调用的http调用
- 17. 如何编写测试类来测试我的代码?
- 18. 如何在多个测试类中运行一组junit测试?
- 19. 如何将我的测试类转换为JUnit测试用例?
- 20. 如何测试为Hibernate实体编写的Arquillian测试类?
- 21. 如何编写用于OSGi(集成)测试的Arquillian测试类?
- 22. 如何测试在被测试的类中调用的方法?
- 23. 如何在测试设置方法中获取测试类别
- 24. 单元测试组织 - 如何不运行基类测试?
- 25. FEST JUnit-Swing测试noobQ:如何测试主类?
- 26. 如何通过另一个测试才能运行测试类?
- 27. 如何在laravel中使用phpunit测试特定测试类
- 28. Objective-C Singleton超类?
- 29. PHP Singleton扩展类
- 30. AS3:Singleton类与LocalConnection类
与此相关的问题是,当您的测试运行时,全局状态会被修改。请参阅下面的答案以获得更清晰的方式。 – 2014-07-11 20:41:39