单元测试:使用 Spock 或 Mockito 模拟 ThreadContext map impl

unit testing: mock ThreadContext map impl using Spock or Mockito

我的方法是这样的Javaclass...

   //some business logic
   String userId = org.apache.logging.log4j.ThreadContext.get("userId"); //I need mocking for this using Spock or Mockito
   //more business logic
   return map;
}

我正在尝试使用 Spock 框架为上述方法编写测试,而 ThreadContext 妨碍了我 - 我无法将其模拟为 return 我希望的字符串。我试图在 spock 测试设置期间将自定义值放入 ThreadContext 中......(没有用)

    def setupSpec() {
        ThreadContext.put("userId", "sriram")
    }

感谢任何想法,谢谢。

Spock 无法开箱即用地模拟 Java 类 的静态方法,只能模拟 Groovy 类。使用 Mockito、Powermock、JMockit 或我自己的工具 Sarek 等其他工具,这是可能的。不过,如果我是你,我不会那样做。对我来说,您的示例代码可以像这样完美运行:

package de.scrum_master.Whosebug.q65702384

import org.apache.logging.log4j.ThreadContext
import spock.lang.Specification

class Log4JThreadContextTest extends Specification {
  def setupSpec() {
    ThreadContext.put("userId", "sriram")
  }

  def test() {
    expect:
    ThreadContext.get("userId") == "sriram"
  }
}

所以ThreadContext.put("userId", "sriram")做你想做的。如果不是,则您的问题与 Spock 无关,例如:

  • 也许您为错误的线程设置了上下文。然后您需要确定正确的线程并在那里设置上下文。
  • 也许这只是您何时设置 ID 的问题。也许在 setupSpec() 你太早了,因为你的测试代码在执行期间设置了相同的 属性,例如在 //some business logic 部分。
  • 作为上一点的变体,您可能需要先初始化另一个对象,然后触发要设置的用户 ID。您自己的声明只需要在之后出现,无论是在 setupSpec()setup() 还是在您的特征方法中。

仅使用您的伪代码而没有 MCVE 很难再说什么,因为我无法重现该问题。猜测的空间太大了,请学会问好问题,从上一句的link开始。