浏览 3071 次
精华帖 (0) :: 良好帖 (5) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-12-08
fixtures 的数据不会在测试结束后自动清除 ,这样就使得fixtures遗留的数据影响到后来的测试。 相关的争论也持续了很久 ,具体的连接请看 http://dev.rubyonrails.org/ticket/2404 里面的 Rick的patch我在rspec下用了,不见好用,我只能自己搞了一个patch,在rspec的 spec_helper.rb下引入 ,解决了这个问题 。 patch主要的思路是: 每次测试setup运行前插入fixture的数据,保证这个插入 fixtures数据的事务和test运行时的事务是同一个 ,teardown结束前,清空一些类变量, 原有的teardown运行的时候会作事务回滚的动作,这样就可以保证每次测试都回滚圆来插入的 fixtures的数据。 相关的配置 : config.use_transactional_fixtures = true config.use_instantiated_fixtures = false module Test #:nodoc: module Unit #:nodoc: class TestCase #:nodoc: alias_method : old_setup_with_fixtures, :setup_with_fixtures unless method_defined?(: old_setup_with_fixtures) alias_method : old_teardown_with_fixtures, :teardown_with_fixtures unless method_defined?(: old_teardown_with_fixtures) def setup_with_fixtures if use_transactional_fixtures? ActiveRecord::Base.send :increment_open_transactions ActiveRecord::Base.connection.begin_db_transaction close_original_activerecord_transaction_methods end old_setup_with_fixtures if use_transactional_fixtures? open_original_activerecord_transaction_methods end end def teardown_with_fixtures if use_transactional_fixtures? clear_fixtures_states_when_use_transactional_fixtures end old_teardown_with_fixtures end #prevent the next code:alias_method from trigger invoking the self.method_added introspected method class<<TestCase alias old_method_added method_added def method_added(m) #do nothing end end alias_method :setup,:setup_with_fixtures alias_method :teardown,:teardown_with_fixtures #reopen the introspector class method:method_added class<<TestCase alias method_added old_method_added end private def clear_fixtures_states_when_use_transactional_fixtures @@already_loaded_fixtures.clear if @@already_loaded_fixtures @loaded_fixtures.clear if @loaded_fixtures end def close_original_activerecord_transaction_methods self.class.class_eval(%Q[ class<<ActiveRecord::Base alias old_increment_open_transactions increment_open_transactions def increment_open_transactions #do nothing end end ]) ActiveRecord::Base.connection.class.class_eval(%Q[ alias_method : old_begin_db_transaction,:begin_db_transaction def begin_db_transaction #do nothing end ]) end def open_original_activerecord_transaction_methods self.class.class_eval(%Q[ class<<ActiveRecord::Base alias increment_open_transactions old_increment_open_transactions end ]) ActiveRecord::Base.connection.class.class_eval(%Q[ alias_method :begin_db_transaction,: old_begin_db_transaction ]) end end end end 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-12-09
更新了 rails 2.0.1后,跑 rspec 发现一大堆失败,看 activerecord的fixtures.rb代码,发现新版的 activerecord为了提升性能,在Fixtures里用一个类变量缓存了connection, 意味着所有的关于fixtures的插入都是使用同一个connection, 走我的代码的逻辑的话,会因为这个cached connection已经被rollback而导致后续的测试都失败。 还好 Fixtures类也相应增加了一个类方法 : reset_cache. 只要在teardown_with_fixtures调用这个reset_cache就行了。
修改后的代码 如下: module Test #:nodoc: module Unit #:nodoc: class TestCase #:nodoc: alias_method : old_setup_with_fixtures, :setup_with_fixtures unless method_defined?(: old_setup_with_fixtures) alias_method : old_teardown_with_fixtures, :teardown_with_fixtures unless method_defined?(: old_teardown_with_fixtures) def setup_with_fixtures if use_transactional_fixtures? ActiveRecord::Base.send :increment_open_transactions ActiveRecord::Base.connection.begin_db_transaction close_original_activerecord_transaction_methods end old_setup_with_fixtures if use_transactional_fixtures? open_original_activerecord_transaction_methods end end def teardown_with_fixtures if use_transactional_fixtures? Fixtures.send :reset_cache if Fixtures.respond_to?(:reset_cache) clear_fixtures_states_when_use_transactional_fixtures end old_teardown_with_fixtures end #prevent the next code:alias_method from trigger invoking the self.method_added introspected method class<<TestCase alias old_method_added method_added def method_added(m) #do nothing end end alias_method :setup,:setup_with_fixtures alias_method :teardown,:teardown_with_fixtures #reopen the introspector class method:method_added class<<TestCase alias method_added old_method_added end private def clear_fixtures_states_when_use_transactional_fixtures @@already_loaded_fixtures.clear if @@already_loaded_fixtures @loaded_fixtures.clear if @loaded_fixtures end def close_original_activerecord_transaction_methods self.class.class_eval(%Q[ class<<ActiveRecord::Base alias old_increment_open_transactions increment_open_transactions alias old_decrement_open_transactions decrement_open_transactions def increment_open_transactions #do nothing end def decrement_open_transactions #do nothing end end ]) ActiveRecord::Base.connection.class.class_eval(%Q[ alias_method : old_begin_db_transaction,:begin_db_transaction alias_method : old_commit_db_transaction,:commit_db_transaction def begin_db_transaction #do nothing end def commit_db_transaction #do nothing end ]) end def open_original_activerecord_transaction_methods self.class.class_eval(%Q[ class<<ActiveRecord::Base alias increment_open_transactions old_increment_open_transactions alias decrement_open_transactions old_decrement_open_transactions end ]) ActiveRecord::Base.connection.class.class_eval(%Q[ alias_method :begin_db_transaction,: old_begin_db_transaction alias_method :commit_db_transaction,: old_commit_db_transaction ]) end end end end |
|
返回顶楼 | |
发表时间:2007-12-11
你这个方法好,在9月份的时候有过类似讨论:
http://www.iteye.com/topic/51922 你可以把这个方法提交到ror的issue tracker上了。 |
|
返回顶楼 | |
发表时间:2007-12-13
Readonly 写道 你这个方法好,在9月份的时候有过类似讨论: 发上去了。两年多了,居然没有引起足够的注意。http://www.iteye.com/topic/51922 你可以把这个方法提交到ror的issue tracker上了。 看来rails 测试的观点和方式很不一样啊。 |
|
返回顶楼 | |