是否可以使用ruby细化来更改测试中控制器操作的行为?

时间:2017-05-18 16:00:17

标签: ruby-on-rails ruby stubbing refinements

是否可以使用细化功能来存根控制器操作?

我在" my_controller_refinement.rb"

中定义了细化
require "my_controller"

module MyControllerRefinement
  refine MyController do
    def create_item(my_object = {})
      return "test_id"
    end
  end
end

在测试中使用它如下 -

require_relative "my_controller_refinement"

class MyControllerTest < ActionController::TestCase
  using MyControllerRefinement

  test "get item" do
    post :create { my_object: { name: "Test", id: "test_id" } }
    # Post redirects to the show page
    assert_redirected_to action: "show", id: "test_id"
  end
end

测试目录为 -

test/
  -->  my_controller_refinement.rb
  -->  my_controller_test.rb

但是细化并没有开始,实际的控制器动作似乎被调用了。

我是否遗漏了某些东西,或者可以将精炼用于此类&#34;存根&#34; ?

2 个答案:

答案 0 :(得分:1)

由于Refinements目前的工作方式,这项工作无法胜任。文档(下面引用)有完整的独家新闻,但实质上对细化的范围非常狭窄。

  

您只能在顶层激活优化,而不能在任何类,模块或方法范围内激活优化。您可以激活传递给在顶级评估的内核#eval的字符串中的优化。优化分别在文件末尾或eval字符串结尾处有效。

     

改进在范围上是词汇。当控制转移到范围之外时,细化被停用。这意味着,如果您需要或加载文件或调用在当前范围之外定义的方法,则将停用细化。

答案 1 :(得分:0)

正如另一个答案所提到的,优化是词法范围的,这意味着它们只在classend之间的空间中活动。我可以用一个例子来证明这一点:

class OrigClass
  def test_method
    # checks if some methods are defined and calls them if they are
    puts (!! defined? patch_method_1) && patch_method_1
    puts (!! defined? patch_method_2) && patch_method_2
  end
  # the refinement will attempt to overwrite this method
  def patch_method_1; 0; end
end

puts OrigClass.new.test_method # => 0 false

module Refinement
  refine OrigClass do
    # this method is already defined on OrigClass
    def patch_method_1; 1; end
    # this one is not
    def patch_method_2; 2; end
  end
end

# re-open the class to add the refinement
class OrigClass
  using Refinement
  puts new.test_method # => 0 false
  puts new.patch_method_1 # => 1
  puts new.patch_method_2 # => 2
end

puts OrigClass.new.test_method # => 0 false

由于词汇范围的限制,最后两次调用test_method不会使用细化方法。这不是使用您的确切用例(控制器操作),但它是相同的概念,并表明改进证明难以以这种方式使用。