简体   繁体   中英

PowerMock: Mocking static method that affect one test only

My situation:

I would like to add a new test. And I need to mock one static method X of Service class. Unfortunately existing tests are using this static method in some way.

And when I mock X method using PowerMock then other test failed. What is more I shouldn't touch other tests.

Is there any opportunity to mock static methods for one test only? ( using PowerMock).

Thanks in advance.

The easiest way to solve your problem is create new test class and place your tests there.

You can also wrap up this static class with normal class hidden behind interface in your code and stub this interface in your tests.

Last thing you can try is to stub each method of your static class in @SetUp method using:

Mockito.when(StaticClass.method(param)).thenCallRealMethod();

and stub particular method in your test using: Mockito.when(Static.methodYouAreInterested(param)).thenReturn(value);

Sure, it is possible! The only time when you could run into problems is if you are trying to test multiple threads at the same time... I put an example of how to do it below. Enjoy.

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.easymock.EasyMock.*;

import static org.junit.Assert.*;
@RunWith(PowerMockRunner.class)
@PrepareForTest(IdGenerator.class)
public class TestClass {

    @Test
    public void yourTest()
    {
        ServiceRegistrator serTestObj = new ServiceRegistrator();

        PowerMock.mockStatic(IdGenerator.class);
        expect(IdGenerator.generateNewId()).andReturn(42L);
        PowerMock.replay(IdGenerator.class);
        long actualId = IdGenerator.generateNewId();

        PowerMock.verify(IdGenerator.class);
        assertEquals(42L,actualId);
     }

    @Test
    public void unaffectedTest() {
        long actualId = IdGenerator.generateNewId();

        PowerMock.verify(IdGenerator.class);
        assertEquals(3L,actualId);
    }
}

TestClass

public class IdGenerator {
     public static long generateNewId()
      {
        return 3L;
      }
}

For those looking to achieve this using Mockito with PowerMocks, this can be done by adding the @PrepareForTest annotation to the tests themselves that need to mock out the values instead of the test class itself.

In this example, let's pretend there is SomeClass that has a static function ( returnTrue() ) that always returns true like so:

public class SomeClass {
    public static boolean returnTrue() {
        return true;
    }
}

This example shows how we can mock out the static call in one test and allow the original functionality to stay the same in another.

@RunWith(PowerMockRunner.class)
@Config(constants = BuildConfig.class)
@PowerMockIgnore({"org.mockito.*", "android.*"})
public class SomeTest {

  /** Tests that the value is not mocked out or changed at all. */
  @Test
  public void testOriginalFunctionalityStays()
    assertTrue(SomeClass.returnTrue());
  }

  /** Tests that mocking out the value works here, and only here. */
  @PrepareForTest(SomeClass.class)
  @Test
  public void testMockedValueWorks() {
    PowerMockito.mockStatic(SomeClass.class);
    Mockito.when(SomeClass.returnTrue()).thenReturn(false);

    assertFalse(SomeClass.returnTrue())
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM