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

5

我的情况:

我想添加一个新的测试。我需要模拟Service类中的静态方法X。不幸的是,现有的测试在某种程度上使用了这个静态方法。

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

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

提前致谢。


1
你能分享一下代码吗? - DaveH
3个回答

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

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

测试类

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

1
最简单的解决方法是创建一个新的测试类并将测试放在那里。
您还可以使用代码中隐藏在接口后面的普通类包装此静态类,并在测试中存根化此接口。
最后,您可以尝试在@SetUp方法中使用存根化静态类的每个方法:

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

使用以下方法在您的测试中存根特定方法: Mockito.when(Static.methodYouAreInterested(param)).thenReturn(value);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接