2

I have a static method (foo) that calls another static method (bar). I would like to mock the response of bar in my test. Is this possible with PowerMockito or another tool? the only results I can find are for mocking statics inside of non-static methods.

public class SomeClass {
   static List<String> foo() {
      ...
      int barResult = bar();
      ...
   }

   static int bar() {
      // make a database call
      return DAO.getDao().runQuery();
   }
}

And my test will call it like:

@RunWith(PowerMockRunner.class)
public class SomeClassTest {

   @PrepareForTest(SomeClass.class)
   @Test
   public void fooTest() {
      List<String> actualResult = SomeClass.foo();
      assertTrue(...);
   }
}

Am I going to have to mock the internals of bar? So mock the DAO?

GhostCat
  • 137,827
  • 25
  • 176
  • 248
flareback
  • 418
  • 1
  • 4
  • 14
  • Possible duplicate of [Mocking static methods with Mockito](http://stackoverflow.com/questions/21105403/mocking-static-methods-with-mockito) – Nir Alfasi Mar 09 '17 at 19:25
  • 1
    You should not use static methods without a good reason in the first place. Code which is *hard to test* because of accessing static methods in other classes is also *hard to reuse* for the same reason. – Timothy Truckle Mar 09 '17 at 19:46
  • Thanks for the accept :-) – GhostCat Mar 10 '17 at 17:23

2 Answers2

2

You can't do that.

Only PowerMock allows you to mock static methods. But that works by "erasing" all static things within that class that gets "prepared" for testing by PowerMock.

If you were talking about ordinary methods, you could be going for Mockito spies, as those allow for partial mockings.

And just for the record: simply avoid using static, as using it leads to "hard to test" code.

In other words: instead of using the big ugly powermock hammer to "fix" your design problems... Consider fixing your broken design instead and thereby avoiding the need for PowerMock altogether!

And for the record: yes, you could solve your problem by mocking that static call on the DAO class (then you can control what bar() does indirectly. But again: that would just mean to put the "I tested it" label on code that should be reworked instead.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • What if you are using external classes that have static methods? Create wrappers from them? – Alessandroempire Sep 01 '17 at 10:08
  • 1
    @Alessandroempire It depends on how often you would be using them. Keep in mind: when you are directly calling those external static methods in your own code ... you are introducing tight coupling to these classes. So when you decide one day to switch your library - you will have to update all your classes that use that static call. In that sense: as usual, this is about balancing. – GhostCat Sep 01 '17 at 10:16
0

You can do:

@RunWith(PowerMockRunner.class)
@PrepareForTest({SomeClass.class, DAO.class})
public class SomeClassTest {

   @Test
   public void fooTest() {
      PowerMockito.mockStatic(DAO.class);
      Mockito.when(DAO.getDao().runQuery()).return(..);
      List<String> actualResult = SomeClass.foo();
      assertTrue(...);
   }
}