2

I am recently working on TDD with JUnit and Mockito. For some purpose within a method, I am using an Util class (an utility class having methods in project context). The thing is what I am facing is how to mock such classes in Mockito. I am not able to find as such implementation regarding static methods in Mockito. Some suggest using PowerMock on top of Mockito but wouldn't that replace my JunitMockitoRunner?

The way I am using the static function is:

public void doSomething(int x){

    //Some code

    Y y = Util.someStaticMethod(x);

   //Some more code
}

EDIT : Also I read somewhere that using static methods is a code smell and is a sign of bad design. So how should I be refactoring the design and what advantages will I be having as a result?

Sourabh
  • 1,253
  • 6
  • 21
  • 39
  • how does your problem relate to title of your query. – Shailesh Aswal Jun 12 '14 at 05:55
  • Hi Shail, I just provided the EDIT :) – Sourabh Jun 12 '14 at 05:56
  • 1
    In the JDK, several examples of good static only classes. Collections, Arrays... – Aubin Jun 12 '14 at 05:57
  • Is changing the Runner for your test a problem? If so why? – geoand Jun 12 '14 at 05:57
  • I wouldn't say that "`static` methods are a code smell, period". Just like everything else, there's a time and place for them. – awksp Jun 12 '14 at 05:58
  • 1
    I don't think it necessarily indicates bad design (may be it depends on how you use it). it's usually preferred for Utilities. (you can find many examples in java API itself) – Shailesh Aswal Jun 12 '14 at 05:59
  • @Geoand : No there is no such problem. I am just reluctant to do that. I think I am using the JunitMockitoRunner only for initializing the annotation which also I can do it in the setup(). So no such qualms. Also can I create my own runner having both of them run together? Would that be a good practice? – Sourabh Jun 12 '14 at 06:01
  • 1
    @Sourabh If refactoring your code is out of the question, then PowerMock is pretty much your only option! Don't be put off by the fact that it uses it's own runner, that shouldn't be a problem – geoand Jun 12 '14 at 06:10
  • Thank Geoand. I will look into the PowerMock. And then would edit the post or answer my post with the possible problems I came up with and what possible solutions I explored to make this post a useful one for the community. :) – Sourabh Jun 12 '14 at 06:25
  • possible duplicate of [Using TDD approach and avoiding Java static methods](http://stackoverflow.com/questions/14986175/using-tdd-approach-and-avoiding-java-static-methods) – Joe Jun 16 '14 at 13:13

2 Answers2

6

How should I be refactoring the design and what advantages will I be having as a result?

Well, if you need to mock the static utility method, then make it an instance method of an injectable object, so that you can inject a mock implementation of this object. The advantage is that it makes your code more testable:

public class Util {
    public Y someInstanceMethod(X x) {
        ...
    }
}

public class ClassToBeTested {
    private Util util;

    public ClassToBeTested(Util util) {
        this.util = util;
    }

    public void doSomething(int x){

        //Some code

        Y y = util.someInstanceMethod(x);

       //Some more code
    }
}

public class ClassToBeTestedTest {

    public void testDoSomething() {
        Util mockUtil = mock(Util.class);
        ClassToBeTested t = new ClassToBeTested(mockUtil);

        when(mockUtil.someInstanceMethd(3)).thenReturn(...);

        ...
    }
}

That's the main selling point of dependency injection: it makes your code testable.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Hi JB, this was something I was already thinking of but that would basically overkill of static methods in the project. I think I might be using PowerMock after some research if that adhering to the project TDD standards in every manner and if its not having any other related problems. :) Anyways thanks for the reply :) – Sourabh Jun 12 '14 at 06:23
0

I do something like that for mocking static Util classes with jMockit.

public class UtilsTest {
    @After
    public void teardown() {
        Mockit.restoreAllOriginalDefinitions();
    }
    @Test
    public void testMyUtil() {
        Mockit.setUpMocks( MockUtil.class );
    }
}

@MockClass(realClass=Util.class)
public class MockUtil{
    @Mock
    public static MySpecialClass someStaticMethod(int x) {
        return Mockito.mock(MySpecialClass.class);
    }
}
oliholz
  • 7,447
  • 2
  • 43
  • 82