我从未想过我会需要在这个网站上提问,因为一切都已经得到了正常回答,但使用Scalatra。。。我没有找到很多信息,所以在这里:
我没有这方面的经验,所以我可能遗漏了一些东西,但据我所知,如果我想测试我在Scalatra上开发的API,每次运行测试服时我都需要启动服务器,对吧?
第二个问题是,我如何重置方法的调用计数器,这样我就不必计算自测试套件开始以来该方法被调用了多少次?现在使用这个给了我不止一个,因为它计算了以前的测试。
there was one(*instance*).*method*(*parameter*)
我仍然可以通过计数或将测试作为第一次测试来解决这个问题,但这不是一个可持续的解决方案。。。
我发现的其他东西:重置mock上的方法。。。找不到http://docs.mockito.googlecode.com/hg/org/mockito/Mockito.html#17
在类别范围内隔离测试:我们需要添加
val servlet = new Servlet(eventRepoMock)
addServlet(servlet, "/*")
并且我们不能在每次初始化时都重复addServlethttps://etorreborre.github.io/specs2/guide/SPECS2-3.5/org.specs2.guide.Isolation.html
我尝试的最后一件事是:
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
就是其中之一。
现在,由于您正在几个示例中共享mock对象的状态,因此您不仅需要在每个示例之前重置mock状态,还需要使您的规范sequential
:
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)
}
}