【问题标题】:Throw Exception Whenever Package Protected Static Method Is Called Using PowerMock (EasyMock)每当使用 PowerMock (EasyMock) 调用包保护的静态方法时抛出异常
【发布时间】:2020-08-07 15:29:10
【问题描述】:

每当调用 TimeZone.getDefaultRef() 方法时,我都会尝试抛出一个断言异常,以基本上表明在测试期间永远不会调用此方法。问题是它是包保护和静态的,所以我想我不得不使用 PowerMock。这是我的尝试:

@RunWith(PowerMockRunner.class)
@PrepareForTest(TimeZone.class)
public class RandomTestingClass {
    @Before
    public void setup() {
        PowerMock.mockStaticPartialNice(TimeZone.class, "getDefaultRef")
        PowerMock.expectPrivate(TimeZone.class, 
            TimeZone.class.getDeclaredMethod("getDefaultRef")).andStubThrow(new AssertionError());
        PowerMock.replay(TimeZone.class)
    }

    @Test
    public void randomTestThatShouldFailBecauseMethodCallsGetDefaultRefMethod() {
        Calendar.getInstance();
    }

    @Test
    public void randomTestThatShouldPassBecauseMethodDoesNotCallGetDefaultRefMethod() {
        Calendar.getInstance(TimeZone.getTimeZone("GMT"));
    }

    @After
    public void after() {
        PowerMock.verify(TimeZone.class);
    {

我收到错误 java.lang.IllegalStateException: no last call on a mock available,我之前肯定见过,但不确定如何在这种情况下修复。我也愿意接受任何其他更优雅的方式来实现这一点。总结一下:

  1. 如果曾经调用过 Timezone.getDefaultRef(),测试应该会失败
  2. 测试不应仅仅因为从未调用过该方法而失败(EasyMock 期待该方法,但它永远不会出现)
  3. 一个测试失败不应影响其他测试
  4. TimeZone 类的其他所有内容都应该正常运行

【问题讨论】:

    标签: java powermock easymock


    【解决方案1】:

    我正在尝试找到一种解决方法,但快速的答案是该方法未被模拟。在期望期间调用了真正的方法。

    PowerMock 无法模拟由引导类加载器加载的类。 TimeZone 就是其中之一。

    解决方案是调用它来模拟。解释了here。它说您需要准备调用系统类而不是系统类的类。

    但在你的情况下,我不确定你能做到。因为你想知道某个地方是否有什么东西在召唤你的班级。因此,如果您正在寻找使用TimeZone 的任何东西,您就无法准备任何东西。除非您的可能调用者范围有限。

    【讨论】:

    • 再次感谢您。我发现这个堆栈溢出答案可能会提供一些线索。 stackoverflow.com/questions/56786034/… 既然它被委托给了 sun.util 类,那么在它上面使用 Powermock 是实现这一目标的可行策略吗?
    • 好的。我找到了我要找的东西。所以我更新了我的答案。但遗憾的是,我认为您没有一个简单的解决方案。除非你使用 ByteBuddy 或 Byteman 或类似的东西。
    • 嗨,Henri,首先,再次感谢您在这方面的真正超越。这就是我一直在寻找的答案(但不是希望)。我正在研究带有注释的 AspectJ 运行时编织,但我认为在这一点上,最好手动浏览代码库并搜索所有有问题的方法,而不是尝试这种有点随意的自动化方法。再次感谢!
    • 不客气。我认为 AspectJ 也会遇到同样的问题。除非它现在可以使用 Java 代理。一个简单的替代方法是在你不想出现的地方放置一个断点,如果你从不在断点处停下来,你就可以了。当然,这不是自动化测试……
    • 啊,由于某种原因,我什至没有考虑断点。不是完全自动化,但在我完成课程并修复所有内容后进行良好的完整性检查,以确保它不仍然存在。
    猜你喜欢
    • 2016-12-05
    • 2017-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多