3

This may be a simple question, but I could not find an answer with reasonable search. I am trying to make a static method return a value more than once in multiple tests. I fail to achieve this with the mocked static method with PowerMock. To put this simply I have a JUnit test @BeforeClass like this

@RunWith(PowerMockRunner.class)
@PrepareForTest(StaticStuff.class)
public class MyTest extends TestCase {
  @BeforeClass
  public static void init() {
    // Mock some stuff
    PowerMockito.mockStatic(StaticStuff.class);
    Mockito.when(StaticStuff.get()).thenReturn("something");
  }
}

Now, this works for the first test accessing the static method, but the rest will receive 'null' (update: or any other value that the "real" method would return). I can fix the problem simply changing the @BeforeClass to @Before, thus making the static mock be recreated for every test. But afaik, this is not the correct way to do this. For this particular case this will do, but I believe there should be a way to provide information that the method may be called "any times".

Actually I understood from the documentation that the same value should be returned "infinite times by default" (but it doesn't. From Mockito documentation: 'Once stubbed, mocked method will always return stubbed value regardless of how many times it is called.'). Also I would expect that stating the amount of calls should be something this simple (but it isn't):

Mockito.when(StaticStuff.get()).thenReturn("something").times(10);

Maybe I am just missing something?

Ville Myrskyneva
  • 1,560
  • 3
  • 20
  • 35
  • What JUnit / Mockito / PowerMockito versions are using? I don't see this happening in 4.11 / 1.9.5 / 1.5.4. – pingw33n May 27 '14 at 11:32
  • The PowerMock version is 1.5.4. The original problem is part of a bigger test class (and which I can not naturally post here). I simplified the test case a bit, but essentially this is what happens. I will create an actual test with the given code also to test this further. – Ville Myrskyneva May 27 '14 at 12:27
  • JUnit = 4.11 & Mockito = 1.9.5 – Ville Myrskyneva May 27 '14 at 12:36
  • The actual testing involves that the static mocked method returns another mocked object. This replaces "some" behavior in Wicket using Spring. This is actually a merge problem, I just remade the test and the actual implementation was edited meanwhile to include the behavior that I now have to mock with the new test. – Ville Myrskyneva May 27 '14 at 12:44
  • Yeah, I confirmed this in a separate test. I have put the code in paste bin: http://pastebin.com/UuF77Zdy – Ville Myrskyneva May 27 '14 at 13:19
  • Note that the static method returns only once the mocked content "test value". Next time it returns the "default value". (In my actual case the default value happens to be 'null'). – Ville Myrskyneva May 27 '14 at 13:21
  • 2
    See http://stackoverflow.com/questions/11955270/mocking-behaviour-resets-after-each-test-with-powermock – pingw33n May 27 '14 at 14:05

1 Answers1

2

The tests should be independent from each other. If you use JUnit, the order of the tests is not determined at all (see https://github.com/junit-team/junit/wiki/Test-execution-order). I think creating mocks in @BeforeClass is actually a bad practice, since it can cause that the tests are depending on each other. So I would simply recommend to use @Before method to initialize all mocks, and use @BeforeClass only, if you prepare something really common for the tests (like a connection pool or something like that).

Gábor Lipták
  • 9,646
  • 2
  • 59
  • 113
  • I am familiar with the fact that the test are not run in particular order. I am creating the mock in BeforeClass, because it will be exactly the same for all cases, thus re-creating it for all tests would cause needless processing. However I noticed that the same value is always returned in a single test, no matter how many times the mocked method is called. You are correct, but this will not be the answer for the actual question. It may even be prevented to use the mocking in BeforeClass for the reason you explained, but I can not find any information about this. – Ville Myrskyneva May 30 '14 at 08:35
  • 1
    I guess when you use PowermockRunner it probably resets the mocks after each test (I would write it at least that way). So the fact, that the first test is ok means for me, that the first test has the mock prepared inside @BeforeClass, and it is then reseted after the first test. It is only speculation, but I guess this can be true. – Gábor Lipták May 30 '14 at 08:47
  • That sounds possible and it seems to be the case. – Ville Myrskyneva May 30 '14 at 09:27