无法在规范中调用mixin模块方法

时间:2011-04-12 13:34:16

标签: ruby rspec mixins

我有以下模块:

# lib/translator/sms_command.rb
module Translator
  module SmsCommand
    def self.included(klass)
      puts "SmsCommand initialized in #{klass}"
    end
    def alias_command(name)

    end
  end
end

以下规格:

# spec/translator/sms_command_spec.rb
require 'spec_helper'

class ExampleCommand
  include Translator::SmsCommand
  alias_command :x
end

module Translator
  describe SmsCommand do
    describe "#alias_command" do
      it "registers the class with the command registry" do
        Translator::SmsCommand.command_registry.should include_key :x
      end

    end
  end
end

是的#alias_command在这个阶段什么都不做,但那是因为我正在开发它。但是,当我运行我的规范时,我看到......

SmsCommand initialized in ExampleCommand

所以模块肯定是混合在一起的,但是alias_command :xExampleCommand行上的规范barf好像alias_command方法永远不可用。

/spec/translator/sms_command_spec.rb:5:in `<class:ExampleCommand>': undefined method `alias_command' for ExampleCommand:Class (NoMethodError)

虽然我更喜欢mixin模块,但我可以通过继承来解决这个问题。我错过了什么?

2 个答案:

答案 0 :(得分:1)

这是因为它不是包含,而是在类方法中访问alias_command的扩展

class ExampleCommand
  extend Translator::SmsCommand
  alias_command :x
end

答案 1 :(得分:1)

你想定义一个名为alias_command的类方法,不是吗? 在这种情况下,您需要extend带有模块的类,一个简单的include会将包含的方法转换为实例方法!

您可以按照以下广泛接受的方式进行此操作:

module Translator
  module SmsCommand
    def self.included(klass)
      puts "SmsCommand initialized in #{klass}"
      klass.extend ClassMethods
    end
    module ClassMethods
      def alias_command(name)
      end
    end
  end
end

这样,当你包含模块时,它将使用类方法自动扩展目标类!