我想编写rspec测试来验证一个类方法,它通过类名调用包含的模块方法。当我使用module调用模块方法时,它工作得很好,但在通过类名调用时抛出NoMethodError。
module Test
def self.module_mtd
p "test"
end
end
class Burger
include Test
attr_reader :options
def initialize(options={})
@options = options
end
def apply_ketchup
@ketchup = @options[:ketchup]
end
def has_ketchup_on_it?
Burger.module_mtd # Throws NoMethodError
Test.module_mtd #Works fine as expected
@ketchup
end
end
describe Burger do
describe "#apply_ketchup" do
subject { burger }
before { burger.apply_ketchup }
context "with ketchup" do
let(:burger) { Burger.new(:ketchup => true) }
it { should have_ketchup_on_it }
end
context "without ketchup" do
let(:burger) { Burger.new(:ketchup => false) }
it { should_not have_ketchup_on_it }
end
end
end发布于 2017-04-30 14:48:13
问题不在于测试本身,而在于您对类方法如何在Ruby中工作的理解。
module Test
def self.module_mtd
p "test"
end
end声明属于Test的方法。与模块实例方法不同,当您包含模块时,这个方法不会添加到类中。
要从模块中声明类方法,需要使用模块混合模式来扩展单例类:
module Test
# this is called when you include the module
def self.included(base)
# this adds the class methods to the class
base.extend ClassMethods
end
module ClassMethods
def foo
puts "hello world"
end
end
endmodule ClassMethods将foo声明为实例方法的事实似乎有点令人困惑,直到您意识到正在扩展的单例类是" class“的实例。
请参见:
https://stackoverflow.com/questions/43707472
复制相似问题