Gibt es eine elegante Art und Weise zu testen, ob eine Instanz Methode ein Alias ??für eine andere ist?

StackOverflow https://stackoverflow.com/questions/3869668

  •  28-09-2019
  •  | 
  •  

Frage

In einem Unit-Test-I-Test müssen, ob alias Methoden von alias_method definiert haben richtig definiert. Ich kann einfach die gleichen Tests auf den Aliasnamen für ihre Originale verwendet verwenden, aber ich frage mich, ob es eine definitive oder effiziente Lösung. Zum Beispiel ist es eine Möglichkeit zu 1) dereferenzieren ein Verfahren Alias ??und die Rück Namen seines Originals, 2) erhalten und vergleichen Sie irgendeine Art von zugrundeliegendem Verfahren Kennung oder Adresse, oder 3) erhalten und vergleichen Sie Methodendefinitionen? Zum Beispiel:

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

Verbesserungsvorschläge?

War es hilfreich?

Lösung

Nach der Dokumentation für Methode ,

  

Zwei Methode Objekte sind gleich, wenn das   sind auf das gleiche Objekt gebunden und   enthält die gleichen Körper.

Beim Object#method und Vergleichen der Method Objekte dass es wird überprüft, gibt, dass die Methoden sind äquivalent:

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

Andere Tipps

bk1e Methode funktioniert die meiste Zeit, aber ich gerade passiert ist, den Fall zu treffen, wo es nicht funktioniert:

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

Der Ausgang in Ruby 1.9 erzeugt wird, nicht sicher, ob es ein Fehler ist oder nicht, da Ruby 1.8 erzeugt true für die letzte Zeile. Also, wenn Sie 1.9 verwenden, seien Sie vorsichtig, wenn Sie eine vererbte Klasse Methode Aliasing (wie Klasse # neu), sind diese beiden Methoden gebunden an das gleiche Objekt (das Klassenobjekt Stream), aber sie werden nicht als gleichwertig von Ruby 1.9 .

Meine Abhilfe ist einfach - alias die ursprüngliche Methode erneut und testen Sie die Gleichheit der beiden Aliase:

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

Hope, das hilft.

UPDATE:

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

So Method#== sollte in diesem Fall falsch zurückgeben, da eine super Aufruf verschiedene Methoden aufrufen würde; es ist kein Fehler.

MyClass.instance_method(:foo) Aufruf führt UnboundMethod Beispiel, die hat eql? Verfahren.

Die Antwort ist also:

describe MyClass do
  subject { described_class }

  specify do
    expect(subject.instance_method(:foo)).to be_eql(subject.instance_method(:bar))
  end
end
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top