Ruby on rails 如何在rspec中对控制器进行修补?
场景 存在并发性可能导致重复密钥错误的争用情况。例如:Ruby on rails 如何在rspec中对控制器进行修补?,ruby-on-rails,ruby-on-rails-4,rspec,Ruby On Rails,Ruby On Rails 4,Rspec,场景 存在并发性可能导致重复密钥错误的争用情况。例如: def before_create_customer_by_external_id end def create_customer_from_external_id(external_id = nil) @customer = current_account.customers.create!(external_id: external_id || @external_id) end def set_new_or_old_custo
def before_create_customer_by_external_id
end
def create_customer_from_external_id(external_id = nil)
@customer = current_account.customers.create!(external_id: external_id || @external_id)
end
def set_new_or_old_customer_by_external_id
if @customer.blank?
before_create_customer_by_external_id
create_customer_from_external_id
end
rescue ActiveRecord::RecordInvalid => e
raise e unless Customer.external_id_exception?(e)
@customer = current_account.customers.find_by_external_id(@external_id)
end
测试
现在,为了测试竞赛案例(基于的答案),我们只需要在通过外部id创建客户之前使用monkey patch,调用从外部id创建客户
问题
如何做到这一点而不重写整个类并出现“method not found”(方法未找到)错误?经过深入研究,我提出了以下解决方案:
context 'with race condition' do
it 'should hit race case and do what is expected' do
ControllerToOverride.class_eval do
def before_create_new_customer_by_external_id
create_customer_from_external_id
end
end
# ...expect...
ControllerToOverride.class_eval do
undef before_create_new_customer_by_external_id
end
end
end
我通过使用代码覆盖率工具和调试语句验证了它是否达到了要求
很高兴知道这里有没有更干净的路
编辑2020-04-24
根据注释,我们应该unde
这个方法,这样它就不会影响后续的测试。参考:
我没有验证这一点,因为我不再有这个测试套件。请让我知道它是否有效。经过一些挖掘,我想出了以下解决方案:
context 'with race condition' do
it 'should hit race case and do what is expected' do
ControllerToOverride.class_eval do
def before_create_new_customer_by_external_id
create_customer_from_external_id
end
end
# ...expect...
ControllerToOverride.class_eval do
undef before_create_new_customer_by_external_id
end
end
end
我通过使用代码覆盖率工具和调试语句验证了它是否达到了要求
很高兴知道这里有没有更干净的路
编辑2020-04-24
根据注释,我们应该unde
这个方法,这样它就不会影响后续的测试。参考:
我没有验证这一点,因为我不再有这个测试套件。如果它不起作用,请告诉我。monkey修补类的一个步骤是创建一个:
这与您的解决方案没有太大区别,但可以将monkeypatch隔离到该上下文块
您可能不需要自定义路由块-rspec为rest方法(编辑、显示、索引等)设置一些虚拟路由
如果此上下文位于descripe ControllerToOverride
块内,则控制器的参数是可选的,除非您已关闭config。为匿名控制器推断\u base\u class\u
从monkey修补类开始的步骤是创建:
这与您的解决方案没有太大区别,但可以将monkeypatch隔离到该上下文块
您可能不需要自定义路由块-rspec为rest方法(编辑、显示、索引等)设置一些虚拟路由
如果此上下文位于descripe ControllerToOverride
块内,则控制器的参数是可选的,除非您已关闭config。为匿名控制器推断基本类,这也将更改后续规范的类-随机规范排序,影响可能是confusing@FrederickCheung我在后面添加了一个undef
,我相信这将解决这个问题。这也将改变后续规范的类-随机规范排序,效果可能会更好confusing@FrederickCheung我在后面添加了一个undef
,我相信这会解决这个问题“undefined method`controller'for#(NoMethodError)”。这实际上是扩展(通过正确的继承)还是替换控制器?这将创建控制器的匿名子类。只有在标记为控制器规范的规范中,才能调用此方法。我为#(NoMethodError)获得了一个“undefined method`controller”“用这个。这实际上是扩展(通过正确的继承)还是替换控制器?这会创建控制器的匿名子类。只有在被标记为控制器规范的规范中,才能调用此函数。