Предположим, у меня есть этот класс:
class Defaults {
def doSomething(regular: String, default: Option[String] = None) = {
println(s"Doing something: $regular, $default")
}
}
Я хочу проверить, что какой-то другой класс вызывает метод doSomething()
для экземпляра Defaults
без передачи второго аргумента:
defaults.doSomething("abcd") // second argument is None implicitly
Однако насмешка над классом Defaults
работает некорректно. Поскольку значения по умолчанию для аргументов метода скомпилированы как скрытые методы в том же классе, mock[Defaults]
возвращает объект, в котором эти скрытые методы возвращают null
вместо None
, поэтому этот тест не пройден:
class Test extends FreeSpec with ShouldMatchers with MockitoSugar {
"Defaults" - {
"should be called with default argument" in {
val d = mock[Defaults]
d.doSomething("abcd")
verify(d).doSomething("abcd", None)
}
}
}
Ошибка:
Argument(s) are different! Wanted:
defaults.doSomething("abcd", None);
-> at defaults.Test$$anonfun$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(Test.scala:14)
Actual invocation has different arguments:
defaults.doSomething("abcd", null);
-> at defaults.Test$$anonfun$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(Test.scala:12)
Причина этого ясна, но есть ли разумный обходной путь? Единственное, что я вижу, это использовать spy()
вместо mock()
, но мой фиктивный класс содержит множество методов, которые в этом случае мне придется явно имитировать, а я этого не хочу.
d
- это просто стандартный прокси-сервер Java, который внутренне вызывает реальный экземплярDefaults
. Поскольку в Java нет понятия парадигмы Some/None, она будет использовать null при динамической привязке аргументов - для Java ваш метод doSomething() является обычным методом с двумя параметрами, поэтому отражающий вызов должен будет заполнить список аргументов чем-то , что в вашем случаеnull
. Кстати, вы пытались решить эту проблему с помощью родного ScalaMock? - person Pavel Lechev   schedule 12.09.2016