Как дразнить метод с функциональными аргументами в Scala?

Я пытаюсь дразнить вызов метода, который берет аргумент вызова по имени:

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)
      }
   }
}

Я, прежде всего, интересуюсь Mockito, так как это - то, что я использую, но мне было бы интересно видеть, способна ли какая-либо из главных ложных платформ к этому виду тестирования. Тест перестал работать во времени выполнения на verify строка, с ошибкой как

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)  

Если я понимаю ситуацию правильно, компилятор неявно переносится t в функции nullary, которая возвращается t. Ложная платформа тогда сравнивает ту функцию с той, произведенной в тестовом коде, который эквивалентен, но нет equals().

Мой случай является относительно простой версией проблемы, но я думаю, что это было бы проблемой с любой функцией высшего порядка.

20
задан Aaron Novstrup 28 January 2010 в 20:48
поделиться

2 ответа

Это выглядит уродливо, но надеюсь, что это поможет вам найти хорошее решение:

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() 
      })
}
10
ответ дан 30 November 2019 в 01:28
поделиться

Эта проблема, по-видимому, специфична для повторных вызовов, потому что в регулярных функциях более высокого порядка вы можете сопоставить с помощью явного объекта FunctionX:

Verify (Collaborator) .somethingelse (любая (функция2 [строка, вещь]))

В повторном случае обертывание аргумента в функцию0 выполняется неявно, и ответ Алексея показывает, как вызовать издевательства с явным параметром.

Вы могли бы написать что-то похожее на ваше собственное убедитесь, что применит бы аргументы, захваченные Mockito.

Mockito внутренне записи записывает вызов и их аргументы с E.g. http://code.google.com/p/mockito/source/browse/trunk/src/org/mockito/internal/matchers/capturationMatcher.java

1
ответ дан 30 November 2019 в 01:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: