rails的fixtures有一个令人讨厌的地方:
fixtures 的数据不会在测试结束后自动清除 ,这样就使得fixtures遗留的数据影响到后来的测试。
相关的争论也持续了很久 ,具体的连接请看 http://dev.rubyonrails.org/ticket/2404
里面的 Rick的patch我在rspec下用了,不见好用,我只能自己搞了一个patch,在rspec的 spec_helper.rb下引入
,解决了这个问题 。
patch主要的思路是: 每次测试setup运行前插入fixture的数据,保证这个插入 fixtures数据的事务和test运行时的事务是同一个 ,teardown结束前,清空一些类变量, 原有的teardown运行的时候会作事务回滚的动作,这样就可以保证每次测试都回滚圆来插入的 fixtures的数据。
相关的配置 :
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
评论
firebody
2007-12-13
Readonly 写道
你这个方法好,在9月份的时候有过类似讨论:
http://www.javaeye.com/topic/51922
你可以把这个方法提交到ror的issue tracker上了。
发上去了。两年多了,居然没有引起足够的注意。http://www.javaeye.com/topic/51922
你可以把这个方法提交到ror的issue tracker上了。
看来rails 测试的观点和方式很不一样啊。
Readonly
2007-12-11
你这个方法好,在9月份的时候有过类似讨论:
http://www.javaeye.com/topic/51922
你可以把这个方法提交到ror的issue tracker上了。
http://www.javaeye.com/topic/51922
你可以把这个方法提交到ror的issue tracker上了。
firebody
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
发表评论
提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则
- 浏览: 22309 次
- 性别:


- 详细资料
搜索本博客
最近加入圈子
最新评论
-
谈谈应用ORM框架针对遗留 ...
BaseService extends HibernateDAOSupport? ...
-- by sslaowan -
谁了解Paulo提出的String ...
可以用google scholar
-- by tiantian911 -
关于实现一个rails smart ...
nihongye 写道firebody 写道LRU频繁的话,性能应该会很差 不知 ...
-- by firebody -
关于实现一个rails smart ...
firebody 写道LRU频繁的话,性能应该会很差 不知道这个猜测是从哪里来的 ...
-- by nihongye -
谈谈应用ORM框架针对遗留 ...
我也经常会为了少写一些代码而使用继承,而不是用工具类,这样会在心里上有一种更直观 ...
-- by downpour






评论排行榜