【问题标题】:Why is this specs2 test using Mockito passing?为什么这个 specs2 测试使用 Mockito 通过?
【发布时间】:2013-12-06 16:58:23
【问题描述】:

假设我有这个接口和类:

abstract class SomeInterface{
  def doSomething : Unit
}

class ClassBeingTested(interface : SomeInterface){
  def doSomethingWithInterface : Unit = {
    Unit
  }
}

请注意,doSomethingWithInterface 方法实际上并没有对接口做任何事情。

我这样为它创建一个测试:

import org.specs2.mutable._
import org.specs2.mock._
import org.mockito.Matchers
import org.specs2.specification.Scope

trait TestEnvironment extends Scope with Mockito{
  val interface = mock[SomeInterface]
  val test = new ClassBeingTested(interface)
}

class ClassBeingTestedSpec extends Specification{
  "The ClassBeingTested" should {
    "#doSomethingWithInterface" in {
      "calls the doSomething method of the given interface" in new TestEnvironment {
        test.doSomethingWithInterface
        there was one(interface).doSomething
      }
    }
  }
}

此测试通过。为什么?我是不是设置错了?

当我摆脱范围时:

class ClassBeingTestedSpec extends Specification with Mockito{
  "The ClassBeingTested" should {
    "#doSomethingWithInterface" in {
      "calls the doSomething method of the given interface" in {
        val interface = mock[SomeInterface]
        val test = new ClassBeingTested(interface)
        test.doSomethingWithInterface
        there was one(interface).doSomething
      }
    }
  }
}

测试按预期失败:

[info]   x calls the doSomething method of the given interface
[error]      The mock was not called as expected: 
[error]      Wanted but not invoked:
[error]      someInterface.doSomething();

这两个测试有什么区别?为什么第一个应该失败时通过了?这不是 Scopes 的预期用途吗?

【问题讨论】:

    标签: scala mockito specs2


    【解决方案1】:

    当您将 Mockito 特征与另一个特征混合时,您可以创建像 there was one(interface).doSomething 这样的期望。如果这样的表达式失败,它只返回一个Result,它不会抛出一个Exception。然后它会在 Scope 中丢失,因为它只是特征体内的“纯”值。

    但是,如果您将 Mockito 特征混合到 mutable.Specification 中,则会在失败时引发异常。这是因为mutable.Specification 类通过混合该特征指定应该有ThrownExpectations

    因此,如果您想创建一个扩展 Scope 的特征,您可以:

    1. 从规范内部创建特征,而不是让它扩展 Mockito:

      class MySpec extends mutable.Specification with Mockito {
        trait TestEnvironment extends Scope {
          val interface = mock[SomeInterface]
          val test = new ClassBeingTested(interface)
        }
        ...
      }
      
    2. 像你一样创建特征和规范,但是混入 org.specs2.execute.ThrownExpectations

      trait TestEnvironment extends Scope with Mockito with ThrownExpectations {
        val interface = mock[SomeInterface]
        val test = new ClassBeingTested(interface)
      }
      
      class MySpec extends mutable.Specification with Mockito {
        ...
      }
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多