问题:
假设我们有两种不同的服务
class ServiceA(serviceB: ServiceB) {
def methodA(): String = {
"methodA called"
serviceB.methodB()
}
def methodA2(): String = {
"methodA2 called"
serviceB.methodB()
}
}
我编写了两个测试方法,并尝试验证methodB是否被调用。当我分别运行两个测试用例时,测试通过。当我运行所有测试方法时,验证为第二次测试给出了错误的结果。 在测试类方面,的Mockito验证记录mock对象上的所有呼叫。我认为在每次测试后,mockito-scala应该重置模拟对象的验证计数
class ServiceATest extends FlatSpec with IdiomaticMockito {
val serviceB: ServiceB = mock[ServiceB]
val serviceA: ServiceA = new ServiceA(serviceB)
"methodA" should "called" in {
serviceA.methodA()
serviceB.methodB wasCalled once // Passes
}
"methodA2" should "called" in {
serviceA.methodA2()
serviceB.methodB wasCalled once // Fail. was 2 times
}
}
我尝试过使用Mockito-core,它给出了同样的错误。
答案 0 :(得分:2)
您的serviceA
和serviceB
对象实际上是测试装置,但是您以错误的方式共享它们。使用像您这样的代码,所有测试将共享相同的对象,这意味着测试将通过共享的脏状态相互交互。 ScalaTest支持多种方式为share fixtures。一项所述的清洁器的方式是loan pattern如:
class ServiceATest extends FlatSpec with IdiomaticMockito {
def withServicesAandBMock(testCode: (ServiceA, ServiceB) => Any) {
val serviceB: ServiceB = mock[ServiceB]
val serviceA: ServiceA = new ServiceA(serviceB)
testCode(serviceA, serviceB)
}
"methodA" should "called" in withServicesAandBMock { (serviceA, serviceB) =>
serviceA.methodA()
serviceB.methodB wasCalled once // Passes
}
"methodA2" should "called" in withServicesAandBMock { (serviceA, serviceB) =>
serviceA.methodA2()
serviceB.methodB wasCalled once // now passes as well
}
}
另外,您可以使用ResetMocksAfterEachTest
class ServiceATest extends FlatSpec with IdiomaticMockito with ResetMocksAfterEachTest {
val serviceB: ServiceB = mock[ServiceB]
val serviceA: ServiceA = new ServiceA(serviceB)
"methodA" should "called" in {
serviceA.methodA()
serviceB.methodB wasCalled once // Passes
}
"methodA2" should "called" in {
serviceA.methodA2()
serviceB.methodB wasCalled once // now passes as well
}
}
但是恕我直言,这是一种作弊行为