Y at-il une façon élégante de tester si une méthode d'instance est un alias pour un autre?

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

  •  28-09-2019
  •  | 
  •  

Question

Dans un test unitaire je dois tester si ont été correctement défini des méthodes d'alias définis par alias_method. Je pourrais simplement utiliser les mêmes tests sur les alias utilisés pour leurs originaux, mais je me demande s'il y a une solution plus définitive ou efficace. Par exemple, est-il un moyen de 1) déréférencer un alias de méthode et retourne son nom d'origine, 2) get et comparer une sorte de sous-jacents identifiant ou adresse méthode ou 3) get et comparer les définitions de méthode? Par exemple:

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

Suggestions?

Était-ce utile?

La solution

Selon la documentation Méthode ,

  

Deux objets de méthode sont égales si ce   sont liés au même objet et   contenir le même corps.

Object#method et comparer les objets qui Method il retourne vérifiera que les méthodes sont équivalentes:

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

Autres conseils

La méthode de bk1e fonctionne la plupart du temps, mais je vient de se passer de frapper le cas où il ne fonctionne pas:

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

La sortie est produite en Ruby 1.9, pas sûr que ce soit un bug ou non, puisque Ruby 1.8 produit true pour la dernière ligne. Donc, si vous utilisez 1.9, soyez prudent si vous aliasing une méthode de classe héritée (comme classe # nouveau), ces deux méthodes sont liés au même objet (l'objet de classe Stream), mais ils ne sont pas considérés comme équivalent par Ruby 1.9 .

Ma solution est simple - alias la méthode originale de nouveau et tester l'égalité des deux alias:

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 this helps.

Mise à jour:

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

Alors Method#== devrait revenir faux dans ce cas depuis un appel super invoquerait différentes méthodes; il est pas un bug.

L'appel MyClass.instance_method(:foo) entraînera UnboundMethod par exemple, qui a eql? méthode.

La réponse est:

describe MyClass do
  subject { described_class }

  specify do
    expect(subject.instance_method(:foo)).to be_eql(subject.instance_method(:bar))
  end
end
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top