回答
看看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