Search code examples
javamockitolog4jspock

unit testing: mock ThreadContext map impl using Spock or Mockito


My method is in a Java class like this...

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

I am trying to write a test for the above method using Spock framework and ThreadContext is getting in the way - I couldn't mock it to return a string of my wish. I tried to put a custom value into the ThreadContext during setup of the spock test...(didn't work)

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

Solution

  • Spock cannot mock static methods of Java classes out of the box, only Groovy classes. With additional tools such as Mockito, Powermock, JMockit or my own tool Sarek this is possible. I would not go that way if I were you, though. For me your sample code runs flawlessly like this:

    package de.scrum_master.stackoverflow.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"
      }
    }
    

    So ThreadContext.put("userId", "sriram") does what you want. If it does not, your problem is something unrelated to Spock, for example:

    • Maybe you set the context for the wrong thread. Then you need to identify the correct thread and set the context there.
    • Maybe it is simply a matter of when you set the ID. Maybe in setupSpec() you are just too early because your code under test sets the same property during execution, e.g. in the //some business logic section.
    • As a variation of the previous point, maybe you need to initialise another object first which then triggers the user ID to be set. Your own statement just needs to come afterwards, no matter if in setupSpec(), setup() or somewhere in your feature method.