Unit testing 如何使用Scalatra、Specs2、Mockito重置模拟调用计数器
我从来没有想过我会在这个网站上问一个问题,因为一切都已经正常回答,但与Scalatra。。。我没有找到太多的信息,所以这里是: 我没有这方面的经验,所以可能我遗漏了一些东西,但据我所知,如果我想测试我在Scalatra上开发的API,我需要在每次运行测试套件时启动服务器,对吗 第二个问题,我如何重置方法上的调用计数器,这样我就不必计算自测试套件开始以来该方法被调用了多少次?现在使用这个给我不止一个,因为它计算了以前的测试Unit testing 如何使用Scalatra、Specs2、Mockito重置模拟调用计数器,unit-testing,mockito,specs2,scalatra,Unit Testing,Mockito,Specs2,Scalatra,我从来没有想过我会在这个网站上问一个问题,因为一切都已经正常回答,但与Scalatra。。。我没有找到太多的信息,所以这里是: 我没有这方面的经验,所以可能我遗漏了一些东西,但据我所知,如果我想测试我在Scalatra上开发的API,我需要在每次运行测试套件时启动服务器,对吗 第二个问题,我如何重置方法上的调用计数器,这样我就不必计算自测试套件开始以来该方法被调用了多少次?现在使用这个给我不止一个,因为它计算了以前的测试 there was one(*instance*).*method*(*p
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方法只是没有被调用。记录器中没有任何内容,所有测试都会崩溃。尽管如此,我现在仍然可以接受以前不推荐的示例。我只是想提一下。如果有人遇到过和我一样的问题,也许我可以给他一些时间。再次感谢埃里克!