对于测试类,我试图添加一个模块:
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
如何让测试重新开始?谢谢
答案 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)重命名呼叫并且是常规方法调用。