Я столкнулся с проблемой, когда имитировали методы, которые имеют границы просмотра типов своих параметров, используя Mockito и Specs2. Проще говоря, поскольку привязка вида переводится в дополнительный неявный аргумент метода, Mockito не может согласовать вызов, описанный ожиданием, с фактическими аргументами, которые получает макет:
Например:
//Receiver.scala
class Receiver {
def methodWithViewBound[T <% WrappedString](w : T) : Unit = {
//noop!
}
}
//WrappedString.scala
class WrappedString(val wrapped : String) {
}
//TestMockedMethodWithViewBound.scala
import org.specs2.mutable._
import org.specs2.specification._
import org.specs2.mock._
import org.mockito.Matchers
class TestMockedMethodWithViewBound extends Specification with Mockito {
implicit def wrapString(s : String) : WrappedString = new WrappedString(s);
implicit def unwrapString(w : WrappedString) : String = w.wrapped;
"Mockito" should {
"Allow mocking of methods whose argument types include a view bound, using a matcher" in {
val receiver = mock[Receiver]
receiver.methodWithViewBound("Testing")
there was one(receiver).methodWithViewBound(Matchers.eq("Testing"))
}
"Allow mocking of methods whose argument types include a view bound, using an argument literal" in {
val receiver = mock[Receiver]
receiver.methodWithViewBound("Testing")
there was one(receiver).methodWithViewBound("Testing")
}
}
}
Вывод этого дает:
[15:18:46] [tim@ahtanum ../tim/Projects/MockitoTest] $ sbt test
[info] Set current project to Mockito View Bounds Test (in build file:/home/tim/Projects/MockitoTest/)
[info] Compiling 1 Scala source to /home/tim/Projects/MockitoTest/target/scala-2.9.1/test-classes...
[info] Mockito should
[error] x Allow mocking of methods whose argument types include a view bound
[error] The mock was not called as expected:
[error] Invalid use of argument matchers!
[error] 2 matchers expected, 1 recorded.
[error] This exception may occur if matchers are combined with raw values:
[error] //incorrect:
[error] someMethod(anyObject(), "raw String");
[error] When using matchers, all arguments have to be provided by matchers.
[error] For example:
[error] //correct:
[error] someMethod(anyObject(), eq("String by matcher"));
[error]
[error] For more info see javadoc for Matchers class. (TestMockedMethodWithViewBound.scala:12)
[info]
[info]
[info] Total for specification TestMockedMethodWithViewBound
[info] Finished in 175 ms
[info] 1 example, 1 failure, 0 error
[error] Failed: : Total 1, Failed 1, Errors 0, Passed 0, Skipped 0
[error] Failed tests:
[error] TestMockedMethodWithViewBound
[error] {file:/home/tim/Projects/MockitoTest/}default-3adcf2/test:test: Tests unsuccessful
[error] Total time: 7 s, completed 07-Mar-2012 15:19:47
[15:19:47] [tim@ahtanum ../tim/Projects/MockitoTest] $ sbt test
[info] Set current project to Mockito View Bounds Test (in build file:/home/tim/Projects/MockitoTest/)
[info] Compiling 1 Scala source to /home/tim/Projects/MockitoTest/target/scala-2.9.1/test-classes...
[info] Mockito should
[error] x Allow mocking of methods whose argument types include a view bound, using a matcher
[error] The mock was not called as expected:
[error] Invalid use of argument matchers!
[error] 2 matchers expected, 1 recorded.
[error] This exception may occur if matchers are combined with raw values:
[error] //incorrect:
[error] someMethod(anyObject(), "raw String");
[error] When using matchers, all arguments have to be provided by matchers.
[error] For example:
[error] //correct:
[error] someMethod(anyObject(), eq("String by matcher"));
[error]
[error] For more info see javadoc for Matchers class. (TestMockedMethodWithViewBound.scala:12)
[error] x Allow mocking of methods whose argument types include a view bound, using an argument literal
[error] The mock was not called as expected:
[error] Argument(s) are different! Wanted:
[error] receiver.methodWithViewBound(
[error] "Testing",
[error] ($anonfun$apply$mcV$sp$2) <function1>
[error] );
[error] -> at TestMockedMethodWithViewBound$$anonfun$1$$anonfun$apply$6$$anonfun$apply$2.apply$mcV$sp(TestMockedMethodWithViewBound.scala:22)
[error] Actual invocation has different arguments:
[error] receiver.methodWithViewBound(
[error] "Testing",
[error] ($anonfun$apply$7) <function1>
[error] );
[error] -> at TestMockedMethodWithViewBound$$anonfun$1$$anonfun$apply$6.apply(TestMockedMethodWithViewBound.scala:21)
[error] (TestMockedMethodWithViewBound.scala:19)
[info]
[info]
[info] Total for specification TestMockedMethodWithViewBound
[info] Finished in 325 ms
[info] 2 examples (+1), 2 expectations (+1), 2 failures (+1), 0 error
[error] Failed: : Total 2, Failed 2, Errors 0, Passed 0, Skipped 0
[error] Failed tests:
[error] TestMockedMethodWithViewBound
[error] {file:/home/tim/Projects/MockitoTest/}default-3adcf2/test:test: Tests unsuccessful
[error] Total time: 7 s, completed 07-Mar-2012 15:23:05
... кто-нибудь сталкивался с этой проблемой раньше или сталкивался с каким-либо способом насмешливых методов с границами представления или неявными параметрами с использованием specs2?
Спасибо
Тим