2

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

我在“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

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

我是否遗漏了什么或者不能将改进用于这种“存根”?

4

2 回答 2

2

由于Refinements当前的工作方式,这将不起作用。文档(下面引用)具有完整的独家新闻,但本质上,改进的范围非常狭窄。

您只能在顶层激活细化,而不是在任何类、模块或方法范围内。您可以在传递给 Kernel#eval 的字符串中激活细化,该字符串在顶层进行评估。细化一直有效,直到文件结束或 eval 字符串结束。

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

于 2017-05-18T16:13:20.450 回答
0

正如另一个答案所提到的,细化是词法范围的,这意味着它们仅在classand之间的空间中有效end。我可以用一个例子来展示这一点:

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不使用细化方法。这没有使用您的确切用例(控制器操作),但它是相同的概念,并且表明改进证明很难以这种方式使用。

于 2017-05-18T16:32:37.750 回答