首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何在Scala中使用Mock注解?

如何在Scala中使用Mock注解?
EN

Stack Overflow用户
提问于 2021-11-20 20:32:07
回答 1查看 78关注 0票数 1

我使用scalatest和Scala2.x。

代码语言:javascript
代码运行次数:0
运行
复制
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")
  ...
}

这不是:

代码语言:javascript
代码运行次数:0
运行
复制
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“行得到了这个异常:

代码语言:javascript
代码运行次数:0
运行
复制
[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]   ...
EN

回答 1

Stack Overflow用户

发布于 2021-11-22 10:42:13

就我个人而言,我会完全避免嘲笑,但如果你真的需要它,在Scala中,我会使用像ScalaMock这样的东西,它可以更好地与语言合作。

代码语言:javascript
代码运行次数:0
运行
复制
class Test1 extends AnyFunSuite { 

  val action = mock[Action]
  (action.process _).expects(*).returning("x")
  ...
}

在我看来,@Mock注解依赖于一些custom JUnit runner,它通过将类似于Guice/Spring的依赖注入与模拟相结合,将逻辑注入到测试类中。但是你用错了:

代码语言:javascript
代码运行次数:0
运行
复制
// 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 
  // ...
}

你完全可以这样做:

代码语言:javascript
代码运行次数:0
运行
复制
// 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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70049649

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档