当前位置: 首页 > 知识库问答 >
问题:

模拟对象与测试用例无关的验证

陶元凯
2023-03-14
class ServiceA(serviceB: ServiceB) {

  def methodA(): String = {
    "methodA called"
    serviceB.methodB()
  }

  def methodA2(): String = {
    "methodA2 called"
    serviceB.methodB()
  }
}
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
  }
}

共有1个答案

程禄
2023-03-14

您的ServiceAServiceB对象实际上是测试夹具,但您以错误的方式共享它们。与您的代码一样,相同的对象由所有测试共享,这意味着测试通过共享的脏状态彼此交互。ScalaTest支持多种共享固定装置的方法。其中一种更干净的方法是贷款模式,如:

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

但这是一种欺骗

 类似资料:
  • 遇到了另一个常见的问题,同时为Spring Batch编写单元测试和集成测试组件是如何模拟域对象。一个很好的例子是StepExecutionListener,如下所示: public class NoWorkFoundStepExecutionListener extends StepExecutionListenerSupport { public ExitStatus afterSte

  • 问题内容: 我有一个要测试的类。只要有可能,我都会对该类进行依赖注入,该注入依赖于其他类的对象。但是,我遇到了一种情况,我想在不重新构造代码的情况下模拟对象,而不是应用DI。 这是要测试的课程: 我为此的测试课程是: 我想不出一种解决方案来模拟Dealer类中的打印对象。自从我在Test类中对其进行了模拟,但是它是在被测试的方法中创建的。我做了研究,但找不到任何好处。资源。 我知道从该方法中创建P

  • 现在有另一个类调用 为了对进行单元测试,我们使用了以下方法 我的问题是如何验证同伴方法是否被调用。

  • 我有一些遗留代码,并对我在该代码上所做的增强进行了编写测试。我有一个类SiteSession,并提取了一个接口ISiteSession,以便将依赖项注入到调用类中。 调用类有一个构造函数,在该构造函数中,依赖项被注入到正在测试的控制器CustomerDetails中 现在,我的测试方法已经嘲弄了依赖关系,并且我对为这个控制器或代码的任何其他部分创建的任何测试都没有问题。但是,当调用该控制器上的测试

  • 我试图弄清楚如何进行单元测试,如果我的控制器的URL是正确的安全的。以防万一有人改变了周围的东西,不小心移除了安全设置。 我的controller方法如下所示: 我设置了一个WebTestEnvironment,如下所示: null 然而,如果仔细观察,这只在不向URL发送实际请求时才有帮助,而只在功能级别上测试服务时才有帮助。在我的案例中,抛出了“拒绝访问”异常: 以下两条日志消息值得注意,基本

  • 问题内容: 我知道关于模拟和测试有很多问题,但是我发现没有任何问题可以完美地帮助我,因此我仍然对理解以下内容有疑问: 如果我弄错了,请纠正我,但据我所知,单元测试用于隔离测试一个特定类的业务逻辑,并且如果有外部需要的任何对象,它们将被模拟。因此,例如,如果我有一个简单城市居民的管理系统,该系统将居民添加到列表中并按姓名返回居民(假设:居民仅包含一些基本个人信息),如下所示: 如果现在我要进行单元测