PowerMock:模拟仅影响一个测试的静态方法

时间:2013-06-20 20:43:00

标签: java unit-testing powermock

我的情况:

我想添加一个新测试。我需要模拟Service类的一个静态方法X. 不幸的是,现有测试以某种方式使用这种静态方法。

当我使用PowerMock模拟X方法时,其他测试失败。 更重要的是,我不应该接触其他测试。

是否有机会仅针对一个测试模拟静态方法? (使用PowerMock)。

提前致谢。

3 个答案:

答案 0 :(得分:1)

解决问题的最简单方法是创建新的测试类并将测试放在那里。

你也可以用你的代码中隐藏在接口后面的普通类来包装这个静态类,并在你的测试中存根这个接口。

您可以尝试的最后一件事是使用以下方法在@SetUp方法中存储静态类的每个方法:

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

并在您的测试中使用以下特定方法: Mockito.when(Static.methodYouAreInterested(PARAM))thenReturn(值);

答案 1 :(得分:1)

当然,有可能!你可能遇到问题的唯一一次是你是否试图同时测试多个线程...我在下面举了一个如何做的例子。享受。

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;
      }
}

答案 2 :(得分:1)

对于那些希望将Mockito与PowerMocks结合使用的人,可以通过在测试本身中添加@PrepareForTest批注来完成,这些批注需要模拟值而不是测试类本身。

在此示例中,我们假设有一个具有静态函数(SomeClass)的returnTrue(),该函数始终返回true,如下所示:

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

此示例说明了我们如何在一个测试中模拟出静态调用,并允许原始功能在另一个测试中保持不变。

@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())
  }
}