unit-testing - 如何使用 Scalatra、Specs2、Mockito 重置模拟调用计数器

标签 unit-testing mockito specs2 scalatra

我从没想过我需要在这个网站上提问,因为一切都已经正常回答了,但是使用 Scalatra ......我没有找到很多信息,所以这里是:

我对这一切都没有经验,所以也许我遗漏了一些东西,但据我了解,如果我想测试我在 Scalatra 上开发的 API,我需要在每次运行测试套件时启动服务器,对吧?

第二个问题,如何重置方法的调用计数器,这样我就不必计算自测试套件开始以来该方法被调用了多少次?现在使用它给我不止一个,因为它计算了以前的测试。

there was one(*instance*).*method*(*parameter*)

我仍然可以通过计算或将测试作为现在的第一个测试来解决这个问题,但这不是一个可持续的解决方案......

我发现的其他东西: 模拟上的重置方法...未找到 http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#17

在类范围内隔离测试: 我们需要添加

val servlet = new Servlet(eventRepoMock)
addServlet(servlet, "/*")

而且我们不能在每次初始化时都重复 addServlet https://etorreborre.github.io/specs2/guide/SPECS2-3.5/org.specs2.guide.Isolation.html

我尝试的最后一件事是:

servlet.repo = mock[EventRepo]

但是 repo 是一个值,我不能这样改变它。

这些“解决方案”都不是很干净,所以我想知道是否有人有一个天才的想法可以解决这个问题!?

提前致谢!

编辑: 多亏了埃里克的评论,上面的问题已经解决了(这很容易),但现在我遇到了问题,因为我正在测试异步调用的 get/post,所以重置模拟不会在正确的时间发生……有什么建议吗?

这是代码的简化版本:

class EventServiceSpec extends ScalatraSpec with Mockito with Before { def is = s2"""
Event Service

GET an existing event
must return status 200                              $get_status200
must return the event with id = :id                 $get_rightEventElement
must call findById once on the event repository     $get_findByIdOnRepo
"""

lazy val anEvent = Event(1, "Some Event"
lazy val eventsBaseUrl = "/events"
lazy val existingEventUrl = s"$eventsBaseUrl/${anEvent.id}"

lazy val eventRepoMock = mock[EventRepository]

lazy val servlet = new Servlet(eventRepoMock)
addServlet(servlet, "/*")

def before = {
    eventRepoMock.findById(anEvent.id) returns Option(anEvent)
    eventRepoMock.findById(unexistingId) returns None
    eventRepoMock.save(anEvent) returns Option(anEvent)
}

def get_status200 = get(existingEventUrl){
    status must_== 200
}

def get_findByIdOnRepo = get(existingEventUrl){
    // TODO count considering previous test... need to find a cleaner way
    there was three(eventRepoMock).findById(anEvent.id)
}

最佳答案

所有 org.mockito.Mockito 函数仍然可以在 specs2 规范中使用,reset 就是其中之一。

现在,由于您要在多个示例之间共享模拟对象的状态,因此您不仅需要在每个示例之前重置模拟状态,还需要使您的规范顺序:

class EventServiceSpec extends ScalatraSpec with Mockito 
  with BeforeAll with BeforeEach { 
  def is = sequential ^ s2"""
  Event Service

  GET an existing event
    must return status 200                              $get_status200
    must return the event with id = :id                 $get_rightEventElement
    must call findById once on the event repository  $get_findByIdOnRepo
  """

  lazy val anEvent = Event(1, "Some Event")
  lazy val eventsBaseUrl = "/events"
  lazy val existingEventUrl = s"$eventsBaseUrl/${anEvent.id}"

  lazy val eventRepoMock = mock[EventRepository]

  lazy val servlet = new Servlet(eventRepoMock)

  def beforeAll = addServlet(servlet, "/*")

  def before = {
    reset(eventRepoMock)
    eventRepoMock.findById(anEvent.id) returns Option(anEvent)
    eventRepoMock.findById(unexistingId) returns None
    eventRepoMock.save(anEvent) returns Option(anEvent)
  }

  def get_status200 = get(existingEventUrl){
    status must_== 200
  }

  def get_findByIdOnRepo = get(existingEventUrl){
   there was one(eventRepoMock).findById(anEvent.id)
  }
}

关于unit-testing - 如何使用 Scalatra、Specs2、Mockito 重置模拟调用计数器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29978134/

相关文章:

scala - Specs2 - "should not equal to"- 如何检查不相等?

sqlite - ServiceStack SqLite创建计算字段

c# - 隔离 Service Fabric ServiceContext 以进行单元测试

python - 如何在 Tkinter 应用程序上运行 unittest?

java - 如何在 mockito 中模拟日期?

spring - 如何在 Mockito 中注入(inject) Prototype bean

java - Mockito 模拟 when() 两种不同类型的泛型方法

java - 你如何模拟 GroovyTestCase 中的方法?

specs2 - Specs2 类中未解析的符号 s2

scala - 使用测试配置玩 2.0 FakeApplication 设置