1
1
package org .mockito
2
2
3
- import java .lang .reflect .Modifier .{ isAbstract , isFinal }
3
+ import java .lang .reflect .Modifier .{isAbstract , isFinal }
4
4
5
5
import org .mockito .exceptions .base .MockitoException
6
6
import org .mockito .exceptions .verification .SmartNullPointerException
7
- import org .mockito .internal .stubbing .defaultanswers .ReturnsMoreEmptyValues
8
7
import org .mockito .internal .util .ObjectMethodsGuru .isToStringMethod
9
8
import org .mockito .invocation .InvocationOnMock
10
9
import org .mockito .stubbing .Answer
10
+ import org .mockito .Answers ._
11
11
12
- import scala .util .{ Failure , Try }
12
+ import scala .concurrent .Future
13
+ import scala .util .{Failure , Try }
13
14
14
- object ScalaDefaultAnswer extends Answer [Any ] {
15
+ trait DefaultAnswer extends Answer [Any ] with Function [InvocationOnMock , Option [Any ]] { self =>
16
+ override def answer (invocation : InvocationOnMock ): Any = apply(invocation).orNull
15
17
16
- private val delegate = new ReturnsMoreEmptyValues
18
+ def orElse (next : DefaultAnswer ): DefaultAnswer = new DefaultAnswer {
19
+ override def apply (invocation : InvocationOnMock ): Option [Any ] = self(invocation).orElse(next.apply(invocation))
20
+ }
21
+ }
22
+
23
+ object DefaultAnswer {
24
+ implicit val defaultAnswer : DefaultAnswer = DefaultParametersHandler orElse ReturnsDefaults orElse SmartNulls
25
+ }
17
26
18
- override def answer (invocation : InvocationOnMock ): Any =
27
+ object DefaultParametersHandler extends DefaultAnswer {
28
+ override def apply (invocation : InvocationOnMock ): Option [Any ] =
19
29
if (invocation.getMethod.getName.contains(" $default$" ) && ! isAbstract(invocation.getMethod.getModifiers))
20
- invocation.callRealMethod()
21
- else
22
- Option (delegate.answer(invocation))
23
- .orElse(emptyValues.get(invocation.getMethod.getReturnType))
24
- .orElse(smartNull(invocation))
25
- .orNull
30
+ Some (invocation.callRealMethod())
31
+ else None
32
+ }
26
33
27
- private def smartNull (invocation : InvocationOnMock ): Option [Any ] = {
34
+ object ReturnsDefaults extends DefaultAnswer {
35
+ override def apply (invocation : InvocationOnMock ): Option [Any ] = Option (RETURNS_DEFAULTS .answer(invocation))
36
+ }
37
+
38
+ object CallsRealMethods extends DefaultAnswer {
39
+ override def apply (invocation : InvocationOnMock ): Option [Any ] = Option (CALLS_REAL_METHODS .answer(invocation))
40
+ }
41
+
42
+ object SmartNulls extends DefaultAnswer {
43
+ override def apply (invocation : InvocationOnMock ): Option [Any ] = {
28
44
val returnType = invocation.getMethod.getReturnType
29
45
30
46
if (! returnType.isPrimitive && ! isFinal(returnType.getModifiers))
@@ -38,13 +54,15 @@ object ScalaDefaultAnswer extends Answer[Any] {
38
54
override def answer (currentInvocation : InvocationOnMock ): Any =
39
55
if (isToStringMethod(currentInvocation.getMethod))
40
56
s """ SmartNull returned by this un-stubbed method call on a mock:
41
- | ${unStubbedInvocation.toString}""" .stripMargin
57
+ | ${unStubbedInvocation.toString}""" .stripMargin
42
58
else
43
59
throw new SmartNullPointerException (
44
60
s """ You have a NullPointerException because this method call was *not* stubbed correctly:
45
- |[ $unStubbedInvocation] on the Mock [ ${unStubbedInvocation.getMock}] """ .stripMargin)
61
+ |[ $unStubbedInvocation] on the Mock [ ${unStubbedInvocation.getMock}] """ .stripMargin)
46
62
}
63
+ }
47
64
65
+ object ReturnsEmptyValues extends DefaultAnswer {
48
66
private [mockito] lazy val emptyValues : Map [Class [_], AnyRef ] = Map (
49
67
classOf [Option [_]] -> Option .empty,
50
68
classOf [List [_]] -> List .empty,
@@ -57,9 +75,11 @@ object ScalaDefaultAnswer extends Answer[Any] {
57
75
classOf [Stream [_]] -> Stream .empty,
58
76
classOf [Vector [_]] -> Vector .empty,
59
77
classOf [Try [_]] -> Failure (new MockitoException (" Auto stub provided by mockito-scala" )),
78
+ classOf [Future [_]] -> Future .failed(new MockitoException (" Auto stub provided by mockito-scala" )),
60
79
classOf [BigDecimal ] -> BigDecimal (0 ),
61
80
classOf [BigInt ] -> BigInt (0 ),
62
81
classOf [StringBuilder ] -> StringBuilder .newBuilder
63
82
)
64
83
84
+ override def apply (invocation : InvocationOnMock ): Option [Any ] = emptyValues.get(invocation.getMethod.getReturnType)
65
85
}
0 commit comments