使用间谍时,规范2中的Mockito会评估一个名字函数

时间:2016-08-04 11:37:08

标签: scala mockito specs2

当我试图运行以下测试代码时,我试图理解'Mockito'(specs2)中'间谍'功能的行为:

import org.specs2.mock.Mockito
import org.specs2.mutable.SpecificationWithJUnit
import org.specs2.specification.Scope

import scala.util.{Failure, Success, Try}

class Foo {
  def foo(f: => Int): Unit = Try { f } match {
    case Success(value) => value
    case Failure(_) => foo1()
  }

  def foo1(): Unit = ???
}

class Boo {
  def boo(): Int = ???
}

class SomeTestClass extends SpecificationWithJUnit {
  "something" should {
    "happen" in new Context {
      mockedBoo.boo returns 1

      spiedFoo.foo(mockedBoo.boo())

      there was one(spiedFoo).foo1
    }
  }
}

trait Context extends Scope with Mockito {
  val spiedFoo = spy(new Foo)

  val mockedBoo = mock[Boo]
}

似乎在打电话时:

spiedFoo.foo(mockedBoo.boo())

在'Foo.foo'有机会运行它的代码之前评估模拟boo。我在'boo'中添加了一个断点并检查了栈跟踪,它告诉我它是由'MethodInterceptorFilter'调用的。更具体地说,'ArgumentsProcessor.argumentsToMatchers'看起来像这样:

if (!isCallRealMethod) {
  // evaluate the byname parameter to collect the argument matchers
  // if an exception is thrown we keep the value to compare it with the actual one (see "with Any" in the MockitoSpec and issue 82)
  val value = try {
    arg.asInstanceOf[Function0[_]].apply()
  } catch {
    case e: Throwable => e
  }
  // during the evaluation of the value some matchers might have been created. pull them.
  val argumentsMatchers = ThreadSafeMockingProgress2.pullLocalizedMatchers
  // if there are no matchers at all being registered this means that
  // we are invoking the method, not verifying it
  // in that case add a new matcher corresponding to the argument (an equals matcher using the value)
  if (argumentsMatchers.isEmpty) matchers.add(new EqualsFunction0(value))
  else {
    // otherwise we add all the existing arguments matchers +
    // we reset the state of the argumentMatchersStorage
    matchers.addAll(argumentsMatchers.map(_.getActualMatcher))
    ThreadSafeMockingProgress2.reportMatchers(argumentsMatchers.map(_.getActualMatcher))
  }
}

它清楚地告诉我们:“评估byname参数以收集参数匹配器。”

如何避免评估by-name参数?

谢谢!

0 个答案:

没有答案