Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

312
Visualizações
RSpec: ¿Cómo comparar argumentos have_received por identidad de objeto?

solía usar expect(subject/double).to haved_received(:a_method).with(args).exactly(n).times para probar que un método se llama con algunos argumentos específicos y se llama exactamente {n} veces. Pero hoy está roto con argumentos son objetos Comparable , eche un vistazo al siguiente código:

configuración

 class A; end class B include Comparable attr_reader :val def initialize(val) @val = val end def <=>(other) self.val <=> other.val end end class S def call(x); end end s = S.new allow(s).to receive(:call)

ahora la siguiente prueba pasó con el objeto normal A

 a1 = A.new a2 = A.new s.call(a1) s.call(a2) expect(s).to have_received(:call).with(a1).exactly(1).times expect(s).to have_received(:call).with(a2).exactly(1).times

pero falló con el objeto Comparable B

 b1 = B.new(0) b2 = B.new(0) s.call(b1) s.call(b2) expect(s).to have_received(:call).with(b1).exactly(1).times expect(s).to have_received(:call).with(b2).exactly(1).times

depuré y vi que el comparador rspec llama al operador de la nave espacial <=> para verificar los argumentos, por lo que considera que b1 y b2 son iguales

 Failure/Error: expect(s).to have_received(:call).with(b1).exactly(1).times expected: 1 time with arguments: received: 2 times with arguments:

¿Qué debo hacer para pasar la prueba?

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Esto sucede porque Comparable implementa == , por lo que sus objetos se tratan como iguales con respecto a == :

 b1 = B.new(0) b2 = B.new(0) b1 == b2 #=> true

Para establecer una restricción basada en la identidad del objeto, puede usar el comparador equal : (o sus alias an_object_equal_to / equal_to )

 expect(s).to have_received(:call).with(an_object_equal_to(b1)).once

Debajo del capó, ¿este emparejador llama equal? :

 b1 = B.new(0) b2 = B.new(0) b1.equal?(b2) #=> false
over 4 years ago · Santiago Trujillo Relatório

0

Mi solución: usar el have_attributes para verificar exactamente object_id del argumento del objeto

 expect(s).to have_received(:call).with(have_attributes(object_id: b1.object_id)) .exactly(1).times expect(s).to have_received(:call).with(have_attributes(object_id: b2.object_id)) .exactly(1).times
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda