在单位测试中,我需要测试是否正确定义了Alias_Method定义的别名方法。我可以简单地对其原件使用的别名使用相同的测试,但是我想知道是否有更确定或有效的解决方案。例如,有没有办法来1)取消方法别名并返回其原始名称,2)获取并比较某种基础方法标识符或地址,或者3)获取和比较方法定义?例如:

class MyClass
  def foo
    # do something
  end

  alias_method :bar, :foo
end

describe MyClass do
  it "method bar should be an alias for method foo" do
    m = MyClass.new
    # ??? identity(m.bar).should == identity(m.foo) ???
  end
end

建议?

有帮助吗?

解决方案

根据文件 方法,

如果绑定到同一对象并包含同一物体,则两个方法对象相等。

打电话 Object#method 并比较 Method 它返回的对象将验证方法是否等效:

m.method(:bar) == m.method(:foo)

其他提示

BK1E的方法大部分时间都可以工作,但是我碰巧碰到了它不起作用的情况:

class Stream
  class << self
    alias_method :open, :new
  end
end

open = Stream.method(:open)
new = Stream.method(:new)
p open, new                   # => #<Method: Stream.new>, #<Method: Class#new>
p open.receiver, new.receiver # => Stream, Stream
p open == new                 # => false

输出是在Ruby 1.9中产生的,不确定它是否是错误,因为Ruby 1.8产生 true 对于最后一行。因此,如果您使用的是1.9,请小心,如果您在使用继承的类方法(例如#new),这两种方法是绑定到同一对象的(类对象 Stream),但它们被认为不是Ruby 1.9的等效物。

我的解决方法很简单 - 再次别名原始方法并测试两个别名的平等:

class << Stream; alias_method :alias_test_open, :new; end
open = Stream.method(:open)
alias_test_open = Stream.method(:alias_test_open)
p open, alias_test_open                   # => #<Method: Stream.new>, #<Method: Stream.new>
p open.receiver, alias_test_open.receiver # => Stream, Stream
p open == alias_test_open                 # => true

希望这可以帮助。

更新:

http://bugs.ruby-lang.org/issues/7613

所以 Method#== 在这种情况下应该返回false,因为 super 呼叫将调用不同的方法;这不是错误。

打电话 MyClass.instance_method(:foo) 将导致 Unboundmethod 实例,有 eql? 方法。

因此答案是:

describe MyClass do
  subject { described_class }

  specify do
    expect(subject.instance_method(:foo)).to be_eql(subject.instance_method(:bar))
  end
end
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top