我使用scalatest和Scala2.x。
import org.mockito.Mockito._
import org.mockito._
import org.mockito.ArgumentMatchers._
class Test1 extends AnyFunSuite {
val action = Mockito.mock(classOf[Action])
when(action.process(anyInt())).thenReturn("x")
...
}
这不是:
import org.mockito.Mockito._
import org.mockito._
import org.mockito.ArgumentMatchers._
class Test1 extends AnyFunSuite {
@Mock
val action = Action()
when(action.process(anyInt())).thenReturn("x")
...
}
我在"when“行得到了这个异常:
[info] Test1 *** ABORTED ***
[info] org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Misplaced or misused argument matcher detected here:
[info]
[info] -> at Test1.<init>(Test1.scala:17)
[info]
[info] You cannot use argument matchers outside of verification or stubbing.
[info] Examples of correct usage of argument matchers:
[info] when(mock.get(anyInt())).thenReturn(null);
[info] doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
[info] verify(mock).someMethod(contains("foo"))
[info]
[info] This message may appear after an NullPointerException if the last matcher is returning an object
[info] like any() but the stubbed method signature expect a primitive argument, in this case,
[info] use primitive alternatives.
[info] when(mock.get(any())); // bad use, will raise NPE
[info] when(mock.get(anyInt())); // correct usage use
[info]
[info] Also, this error might show up because you use argument matchers with methods that cannot be mocked.
[info] Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode().
[info] Mocking methods declared on non-public parent classes is not supported.
[info] at Test1.<init>(Test1.scala:17)
[info] at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
[info] at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
[info] at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
[info] at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
[info] at java.lang.Class.newInstance(Class.java:442)
[info] at org.scalatest.tools.Framework$ScalaTestTask.execute(Framework.scala:450)
[info] at sbt.TestRunner.runTest$1(TestFramework.scala:140)
[info] at sbt.TestRunner.run(TestFramework.scala:155)
[info] at sbt.TestFramework$$anon$3$$anonfun$$lessinit$greater$1.$anonfun$apply$1(TestFramework.scala:318)
[info] ...
发布于 2021-11-22 10:42:13
就我个人而言,我会完全避免嘲笑,但如果你真的需要它,在Scala中,我会使用像ScalaMock这样的东西,它可以更好地与语言合作。
class Test1 extends AnyFunSuite {
val action = mock[Action]
(action.process _).expects(*).returning("x")
...
}
在我看来,@Mock
注解依赖于一些custom JUnit runner,它通过将类似于Guice/Spring的依赖注入与模拟相结合,将逻辑注入到测试类中。但是你用错了:
// Here you would have to configure JUnit runner
// (but Scala test libraries are not really JUnit-based)
class Test1 extends AnyFunSuite {
// Here you would have to configure action as var
// and not initialize it yourself, so that runner could
// create the mocks and put them here using reflection
// after instance initialization
@Mock
var action: Action = _
// Here you could not have the test logic be implemented
// as vals or vars, because it would be executed in object's
// constructor - when action is still unititialized
// (therefore null). JUnit doesn't show this issue as it
// uses @Mock on class attributes, and put @Test logic in
// methods - called only after constructor is completed
// and JUnitRunner injects additional logic
// ...
}
你完全可以这样做:
// use JUnit instead of Scalatest
@RunWith(classOf[MockitoJUnitRunner])
class Test1 {
@Mock
var action: Action = _
@Test
def example(): Unit = {
// ...
}
}
因此,它可以在Scala中工作,但不能在非基于JUnit的测试库中工作。如果您对ScalaTest中的Mockito约定感兴趣,请参阅a dedicated documentation page。
https://stackoverflow.com/questions/70049649
复制相似问题