<p>My motto for Java is "just because Java has static blocks, it doesn't mean that you should be using them." Jokes aside, there are a lot of tricks in Java that make testing a nightmare. Two of the most I hate are Anonymous Classes and Static Blocks. We have a lot of legacy code that make use of Static Blocks and these are one of the annoying points in our push in writing unit tests. Our goal is to be able to write unit tests for classes that depend on this static initialization with minimal code changes. </p>

<p>So far my suggestion to my colleagues is to move the body of the static block into a private static method and call it <code>staticInit</code>. This method can then be called from within the static block. For unit testing another class that depends on this class could easily mock <code>staticInit</code> with <a href="https://jmockit.github.io/" rel="noreferrer">JMockit</a> to not do anything. Let's see this in example.</p>

<pre><code>public class ClassWithStaticInit {
  static {
    System.out.println("static initializer.");
  }
}
</code></pre>

<p>Will be changed to</p>

<pre><code>public class ClassWithStaticInit {
  static {
    staticInit();
  }

  private static void staticInit() {
    System.out.println("static initialized.");
  }
}
</code></pre>

<p>So that we can do the following in a <a href="https://junit.org/junit5/" rel="noreferrer">JUnit</a>.</p>

<pre><code>public class DependentClassTest {
  public static class MockClassWithStaticInit {
    public static void staticInit() {
    }
  }

  @BeforeClass
  public static void setUpBeforeClass() {
    Mockit.redefineMethods(ClassWithStaticInit.class, MockClassWithStaticInit.class);
  }
}
</code></pre>

<p>However this solution also comes with its own problems. You can't run <code>DependentClassTest</code> and <code>ClassWithStaticInitTest</code> on the same JVM since you actually want the static block to run for <code>ClassWithStaticInitTest</code>.</p>

<p>What would be your way of accomplishing this task? Or any better, non-JMockit based solutions that you think would work cleaner?</p>

[{'answer_id': 61153, 'author': 'Justin Standard', 'author_id': 92, 'author_profile': 'https://Stackoverflow.com/users/92', 'pm_score': 3, 'selected': False, 'text': "<p>Sounds to me like you are treating a symptom: poor design with dependencies on static initialization.  Maybe some refactoring is the real solution.  It sounds like you've already done a little refactoring with your <code>staticInit()</code> function, but maybe that function needs to be called from the constructor, not from a static initializer.  If you can do away with static initializers period, you will be better off.  Only you can make this decision (<em>I can't see your codebase</em>) but some refactoring will definitely help.</p>\n\n<p>As for mocking, I use EasyMock, but I have run into the same issue.  Side effects of static initializers in legacy code make testing difficult.  Our answer was to refactor out the static initializer.</p>\n"}, {'answer_id': 61177, 'author': 'Henrik Gustafsson', 'author_id': 2010, 'author_profile': 'https://Stackoverflow.com/users/2010', 'pm_score': 1, 'selected': False, 'text': '<p>I suppose you really want some kind of factory instead of the static initializer.</p>\n\n<p>Some mix of a singleton and an abstract factory would probably be able to get you the same functionality as today, and with good testability, but that would add quite a lot of boiler-plate code, so it might be better to just try to refactor the static stuff away completely or if you could at least get away with some less complex solution. </p>\n\n<p>Hard to tell if it´s possible without seeing your code though.</p>\n'}, {'answer_id': 61190, 'author': 'marcospereira', 'author_id': 4600, 'author_profile': 'https://Stackoverflow.com/users/4600', 'pm_score': 2, 'selected': False, 'text': "<p>You could write your test code in Groovy and easily mock the static method using metaprogramming.</p>\n\n<pre><code>Math.metaClass.'static'.max = { int a, int b -&gt; \n    a + b\n}\n\nMath.max 1, 2\n</code></pre>\n\n<p>If you can't use Groovy, you will really need to refactoring the code (maybe to inject something like a initializator).</p>\n\n<p>Kind Regards</p>\n"}, {'answer_id': 61215, 'author': 'Mike Stone', 'author_id': 122, 'author_profile': 'https://Stackoverflow.com/users/122', 'pm_score': 4, 'selected': True, 'text': "<p>When I run into this problem, I usually do the same thing you describe, except I make the static method protected so I can invoke it manually.  On top of this, I make sure that the method can be invoked multiple times without problems (otherwise it is no better than the static initializer as far as the tests go).</p>\n\n<p>This works reasonably well, and I can actually test that the static initializer method does what I expect/want it to do.  Sometimes it is just easiest to have some static initialization code, and it just isn't worth it to build an overly complex system to replace it.</p>\n\n<p>When I use this mechanism, I make sure to document that the protected method is only exposed for testing purposes, with the hopes that it won't be used by other developers.  This of course may not be a viable solution, for example if the class' interface is externally visible (either as a sub-component of some kind for other teams, or as a public framework).  It is a simple solution to the problem though, and doesn't require a third party library to set up (which I like).</p>\n"}, {'answer_id': 61389, 'author': 'martinatime', 'author_id': 1353, 'author_profile': 'https://Stackoverflow.com/users/1353', 'pm_score': 1, 'selected': False, 'text': '<p>I\'m not super knowledgeable in Mock frameworks so please correct me if I\'m wrong but couldn\'t you possibly have two different Mock objects to cover the situations that you mention? Such as</p>\n\n<pre><code>public static class MockClassWithEmptyStaticInit {\n  public static void staticInit() {\n  }\n}\n</code></pre>\n\n<p>and</p>\n\n<pre><code>public static class MockClassWithStaticInit {\n  public static void staticInit() {\n    System.out.println("static initialized.");\n  }\n}\n</code></pre>\n\n<p>Then you can use them in your different test cases</p>\n\n<pre><code>@BeforeClass\npublic static void setUpBeforeClass() {\n  Mockit.redefineMethods(ClassWithStaticInit.class, \n                         MockClassWithEmptyStaticInit.class);\n}\n</code></pre>\n\n<p>and</p>\n\n<pre><code>@BeforeClass\npublic static void setUpBeforeClass() {\n  Mockit.redefineMethods(ClassWithStaticInit.class, \n                         MockClassWithStaticInit.class);\n}\n</code></pre>\n\n<p>respectively.</p>\n'}, {'answer_id': 144876, 'author': 'Cem Catikkas', 'author_id': 3087, 'author_profile': 'https://Stackoverflow.com/users/3087', 'pm_score': 4, 'selected': False, 'text': '<p>This is going to get into more "Advanced" JMockit. It turns out, you can redefine static initialization blocks in JMockit by creating a <code>public void $clinit()</code> method. So, instead of making this change</p>\n\n<pre><code>public class ClassWithStaticInit {\n  static {\n    staticInit();\n  }\n\n  private static void staticInit() {\n    System.out.println("static initialized.");\n  }\n}\n</code></pre>\n\n<p>we might as well leave <code>ClassWithStaticInit</code> as is and do the following in the <code>MockClassWithStaticInit</code>:</p>\n\n<pre><code>public static class MockClassWithStaticInit {\n  public void $clinit() {\n  }\n}\n</code></pre>\n\n<p>This will in fact allow us to not make any changes in the existing classes.</p>\n'}, {'answer_id': 489018, 'author': 'Jan Kronquist', 'author_id': 43935, 'author_profile': 'https://Stackoverflow.com/users/43935', 'pm_score': 6, 'selected': False, 'text': '<p><a href="http://powermock.org" rel="noreferrer">PowerMock</a> is another mock framework that extends EasyMock and Mockito. With PowerMock you can easily <a href="http://code.google.com/p/powermock/wiki/SuppressUnwantedBehavior" rel="noreferrer">remove unwanted behavior</a> from a class, for example a static initializer. In your example you simply add the following annotations to your JUnit test case:</p>\n\n<pre><code>@RunWith(PowerMockRunner.class)\n@SuppressStaticInitializationFor("some.package.ClassWithStaticInit")\n</code></pre>\n\n<p>PowerMock does not use a Java agent and therefore does not require modification of the JVM startup parameters. You simple add the jar file and the above annotations. </p>\n'}, {'answer_id': 7242341, 'author': 'matsev', 'author_id': 303598, 'author_profile': 'https://Stackoverflow.com/users/303598', 'pm_score': 4, 'selected': False, 'text': '<p>Occasionally, I find static initilizers in classes that my code depends on. If I cannot refactor the code, I use <a href="http://code.google.com/p/powermock/" rel="noreferrer">PowerMock</a>\'s <code>@SuppressStaticInitializationFor</code> annotation to suppress the static initializer:</p>\n\n<pre><code>@RunWith(PowerMockRunner.class)\n@SuppressStaticInitializationFor("com.example.ClassWithStaticInit")\npublic class ClassWithStaticInitTest {\n\n    ClassWithStaticInit tested;\n\n    @Before\n    public void setUp() {\n        tested = new ClassWithStaticInit();\n    }\n\n    @Test\n    public void testSuppressStaticInitializer() {\n        asserNotNull(tested);\n    }\n\n    // more tests...\n}\n</code></pre>\n\n<p>Read more about <a href="http://code.google.com/p/powermock/wiki/SuppressUnwantedBehavior" rel="noreferrer">suppressing unwanted behaviour</a>.</p>\n\n<p>Disclaimer: PowerMock is an open source project developed by two colleagues of mine. </p>\n'}, {'answer_id': 33737521, 'author': 'KidCrippler', 'author_id': 223365, 'author_profile': 'https://Stackoverflow.com/users/223365', 'pm_score': 0, 'selected': False, 'text': '<p>Not really an answer, but just wondering - isn\'t there any way to "reverse" the call to <code>Mockit.redefineMethods</code>?<br>\nIf no such explicit method exists, shouldn\'t executing it again in the following fashion do the trick?</p>\n\n<pre><code>Mockit.redefineMethods(ClassWithStaticInit.class, ClassWithStaticInit.class);\n</code></pre>\n\n<p>If such a method exists, you could execute it in the class\' <code>@AfterClass</code> method, and test <code>ClassWithStaticInitTest</code> with the "original" static initializer block, as if nothing has changed, from the same JVM.</p>\n\n<p>This is just a hunch though, so I may be missing something.</p>\n'}, {'answer_id': 64216523, 'author': 'Sebastian Luna', 'author_id': 7845889, 'author_profile': 'https://Stackoverflow.com/users/7845889', 'pm_score': 0, 'selected': False, 'text': '<p>You can use PowerMock to execute the private method call like:</p>\n<pre><code>ClassWithStaticInit staticInitClass = new ClassWithStaticInit()\nWhitebox.invokeMethod(staticInitClass, &quot;staticInit&quot;);\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/61150', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/3087/']