Pregunta

En una prueba de unidad que necesito para probar si los métodos de alias definidos por alias_method se han definido adecuadamente. Yo podría simplemente utilizar las mismas pruebas sobre los alias usados ??por sus originales, pero me pregunto si hay una solución más definitiva o eficiente. Por ejemplo, ¿hay alguna manera a 1) eliminar la referencia de un alias de método y devolver el nombre del original, 2) get y comparar algún tipo de identificador de método subyacente o la dirección, o 3) get y comparar definiciones de métodos? Por ejemplo:

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

Sugerencias?

¿Fue útil?

Solución

De acuerdo con la documentación para Método ,

  

dos objetos método son iguales si que   están enlazados al mismo objeto y   contener el mismo cuerpo.

Object#method y comparación de los objetos que Method vuelve verificará que los métodos son equivalentes:

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

Otros consejos

El método de bk1e trabaja la mayor parte del tiempo, pero me acaba de pasar a golpear el caso en que no funciona:

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 salida se produce en Ruby 1.9, no está seguro de si se trata de un error o no desde Rubí 1,8 produce true para la última línea. Por lo tanto, si está utilizando 1.9, tenga cuidado si usted está aliasing un método de clase heredada (como Clase # nuevo), estos dos métodos están unidos al mismo objeto (el Stream objeto de clase), pero se considera que no asimilable de Ruby 1.9 .

Mi solución es sencilla - alias el método original de nuevo y probar la igualdad de las dos 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

Espero que esto ayude.

ACTUALIZACIÓN:

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

Así Method#== debe devolver falsa en este caso desde una llamada super invocaría diferentes métodos; que no es un error.

Llamando MyClass.instance_method(:foo) resultará UnboundMethod ejemplo, que tiene eql? método.

Así que la respuesta es:

describe MyClass do
  subject { described_class }

  specify do
    expect(subject.instance_method(:foo)).to be_eql(subject.instance_method(:bar))
  end
end
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top