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

Unit testing 如何使用Scalatra、Specs2、Mockito重置模拟调用计数器,unit-testing,mockito,specs2,scalatra,Unit Testing,Mockito,Specs2,Scalatra,我从来没有想过我会在这个网站上问一个问题,因为一切都已经正常回答,但与Scalatra。。。我没有找到太多的信息,所以这里是: 我没有这方面的经验,所以可能我遗漏了一些东西,但据我所知,如果我想测试我在Scalatra上开发的API,我需要在每次运行测试套件时启动服务器,对吗 第二个问题,我如何重置方法上的调用计数器,这样我就不必计算自测试套件开始以来该方法被调用了多少次?现在使用这个给我不止一个,因为它计算了以前的测试 there was one(*instance*).*method*(*p

我从来没有想过我会在这个网站上问一个问题,因为一切都已经正常回答,但与Scalatra。。。我没有找到太多的信息,所以这里是:

我没有这方面的经验,所以可能我遗漏了一些东西,但据我所知,如果我想测试我在Scalatra上开发的API,我需要在每次运行测试套件时启动服务器,对吗

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

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

我发现的另一件事: 模拟上的重置方法。。。找不到

在类别范围内隔离测试: 我们需要补充一点

val servlet = new Servlet(eventRepoMock)
addServlet(servlet, "/*")
我们不能在每次初始化时重复addServlet

我尝试的最后一件事是:

servlet.repo = mock[EventRepo]
但是
repo
作为一个值,我不能这样改变它

这两个“解决方案”都不是很干净,所以我想知道是否有人有一个天才的想法可以解决这个混乱

提前谢谢你

编辑: 感谢Eric的评论,上面的问题已经解决了(这很容易),但现在我遇到了问题,因为我正在测试get/post,这是一个异步调用,所以重置mock不会在正确的时间发生。。。有什么建议吗

下面是代码的简化版本:

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)
  }
}

所以你的模拟回购协议上的
org.mockito.mockito.reset
方法不起作用了?哦,是的!真管用!我现在觉得有点傻。。。我只尝试了
重置(eventRepoMock)
。。。但是如果我在一个扩展了mockito的类中调用它,
org.mockito.mockito.reset(eventRepoMock)
有什么区别?我也在原始的问题帖子中添加了一个问题,你可以发布一个完整的剪贴(但尽可能简化)吗?你也可以尝试使你的规范
连续化吗?默认情况下,示例是并发执行的,这可能是您看到测试失败的原因。您是否在每次测试之前使用
?对我来说,我需要使用弃用的
BeforeExample
来代替,因为没有调用
before
BeforeExample
被定义为
trait BeforeExample extends beforeach
,所以应该很简单,只需更改导入和扩展/with,对吗?当我尝试它时,before方法只是没有被调用。记录器中没有任何内容,所有测试都会崩溃。尽管如此,我现在仍然可以接受以前不推荐的
示例。我只是想提一下。如果有人遇到过和我一样的问题,也许我可以给他一些时间。再次感谢埃里克!