mockfactory mock scala mocking

mock - ¿Cómo burlarse de un método con argumentos funcionales en Scala?



java mock (3)

Este problema parece ser específico para invocaciones de nombre porque en las funciones regulares de orden superior puede hacer coincidir con el objeto FunctionX explícito:

verificar (colaborador) .somethingElse (cualquiera (Function2 [String, Thing]))

en el caso de by-name, el ajuste del argumento en una Function0 se realiza de manera implícita, y la respuesta de Alexey muestra cómo invocar el simulacro con un parámetro explícito.

Puedes escribir algo similar a tu propio verificador que aplique los argumentos capturados por mockito.

Mockito registra internamente la invocación y sus argumentos con, por ejemplo, http://code.google.com/p/mockito/source/browse/trunk/src/org/mockito/internal/matchers/CapturingMatcher.java

Estoy intentando burlar una llamada de método que toma un argumento de llamada por nombre:

import org.scalatest.WordSpec import org.scalatest.mock.MockitoSugar import org.mockito.Mockito._ import org.junit.runner.RunWith import org.scalatest.junit.JUnitRunner trait Collaborator { def doSomething(t: => Thing) } trait Thing @RunWith(classOf[JUnitRunner]) class Test extends WordSpec with MockitoSugar { "The subject under test" should { "call the collaborator" in { // setup val m = mock[Collaborator] val t = mock[Thing] // test code: this would actually be invoked by the SUT m.doSomething(t) // verify the call verify(m).doSomething(t) } } }

Estoy interesado principalmente en Mockito ya que eso es lo que estoy usando, pero me gustaría ver si alguno de los principales marcos simulados es capaz de realizar este tipo de pruebas. La prueba falla en el tiempo de ejecución en la línea de verify , con un error como

Argument(s) are different! Wanted: collaborator.doSomething( ($anonfun$apply$3) <function> ); -> at Test$$anonfun$1$$anonfun$apply$1.apply(Test.scala:27) Actual invocation has different arguments: collaborator.doSomething( ($anonfun$apply$2) <function> ); -> at Test$$anonfun$1$$anonfun$apply$1.apply(Test.scala:24)

Si estoy entendiendo la situación correctamente, el compilador está envolviendo implícitamente t en una función nula que devuelve t . El marco simulado luego compara esa función con la producida en el código de prueba, que es equivalente pero no equals() .

Mi caso es una versión relativamente simple del problema, pero creo que este sería un problema con cualquier función de orden superior.


Esto parece feo, pero espero que pueda ayudarlo a encontrar una buena solución:

import org.scalatest.mock.MockitoSugar import org.mockito.Mockito._ trait Collaborator { def doSomething(t: => Thing) } trait Thing new MockitoSugar { // setup val m = mock[Collaborator] val t = mock[Thing] m.doSomething(t) classOf[Collaborator].getMethod("doSomething", classOf[Function0[_]]).invoke( verify(m), new Function0[Thing] { def apply() = null override def equals(o: Any): Boolean = t == o.asInstanceOf[Function0[Thing]].apply() }) }


Puedes probar specs2 . En las especificaciones 2, "secuestramos" la clase de Invocation Mockito para tener en cuenta los parámetros de nombre:

trait ByName { def call(i: =>Int) = i } val byname = mock[ByName] byname.call(10) there was one(byname).call(10)