将模块添加到Test Class

时间:2016-05-28 00:44:40

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-4

对于测试类,我试图添加一个模块:

require "test_helper"
require "before_find_helper"

class User::FindOrCreateTest < ActiveSupport::TestCase
  include BeforeFindHelper

模块看起来像这样:

module BeforeFindHelper
  extend ActiveSupport::Concern

  self.before do
    class FakeController < ApplicationController
     ......
    end
  end
end

基本上在控制器中定义before - 块之前一切正常

  before do
    class FakeController < ApplicationController
     ......
    end
  end

但现在使用包含的模块,我在运行测试时遇到此错误:

未定义的方法`之前&#39; for BeforeFindHelper:Module

如何让测试重新开始?谢谢

1 个答案:

答案 0 :(得分:0)

当您包含模块时,您将在模块中提取定义的所有方法before是由模块调用的方法。也就是说,before代码正在调用名为before的方法,并在测试之前将代码块传递给它。

一个有希望的替代方案是定义在模块中定义类的方法,并在before调用中从测试类中调用它。

不幸的是,无法在方法中定义类。但是, 可以在lambda中定义一个类。所以你的模块方法可以返回一个lambda,当被调用时,它定义了类:

module BeforeFindHelper
  extend ActiveSupport::Concern

  def fn_define_fake_controller_class
    -> do
      class FakeController < ApplicationController
       ......
      end
    end
  end
end


class User::FindOrCreateTest < ActiveSupport::TestCase
  include BeforeFindHelper

  before { fn_define_fake_controller_class.() }
end

所有人都说,我对Rails代码的一个担忧是,它经常使用include。在模块级别定义方法并在调用它时将其名称作为模块名称作为前缀并不困难。这清楚地向读者展示了如果他/她想要检查它,在何处找到被调用的方法。这可能是这样的:

module BeforeFindHelper
  extend ActiveSupport::Concern

  def self.fn_define_fake_controller_class
    -> do
      class FakeController < ApplicationController
       ......
      end
    end
  end
end


class User::FindOrCreateTest < ActiveSupport::TestCase

  before { BeforeFindHelper.fn_define_fake_controller_class.() }
end

唯一的区别是1)include已被删除,因为不再需要它,2)当定义fn_define_fake_controller_class时,它前面有self.,和3)调用该方法时,会使用模块名称BeforeFindHelper.fn_define_fake_controller_class.()消除歧义。

想想看,可以通过在定义它的方法中调用lambda来简化这一点,这样在测试代码中你可以调用一个方法,而不是一个方法返回的lambda: / p>

module BeforeFindHelper
  extend ActiveSupport::Concern

  def self.define_fake_controller_class
    -> do
      class FakeController < ApplicationController
       ......
      end
    end.()
  end
end


class User::FindOrCreateTest < ActiveSupport::TestCase

  before { BeforeFindHelper.define_fake_controller_class }
end

差异是1)重命名该方法以表明正在进行定义而不返回lambda(fn); 2)lambda在定义后立即被调用(带.()); 3)重命名呼叫并且是常规方法调用。