如何模拟另一个静态方法调用的静态方法?

时间:2011-09-01 03:43:46

标签: java mocking

我想测试一个静态方法A,它在同一个类中调用另一个静态方法B.我该如何模拟方法B?

2 个答案:

答案 0 :(得分:1)

模拟静态方法 快速摘要

Use the @RunWith(PowerMockRunner.class) annotation at the class-level of the test case.
Use the @PrepareForTest(ClassThatContainsStaticMethod.class) annotation at the class-level of the test case.
Use PowerMock.mockStatic(ClassThatContainsStaticMethod.class) to mock all methods of this class.
Use PowerMock.replay(ClassThatContainsStaticMethod.class) to change the class to replay mode.
Use PowerMock.verify(ClassThatContainsStaticMethod.class) to change the class to verify mode.

实施例 在PowerMock中模拟静态方法需要在PowerMock中使用“mockStatic”方法。假设你有一个类ServiceRegistrator,它有一个名为registerService的方法,如下所示:

public long registerService(Object service) {
   final long id = IdGenerator.generateNewId();
   serviceRegistrations.put(id, service);
   return id;
}

这里感兴趣的是对我们想要模拟的IdGenerator.generateNewId()的静态方法调用。 IdGenerator是一个帮助程序类,它只是为服务生成一个新的ID。它看起来像这样:

public class IdGenerator {

   /**
    * @return A new ID based on the current time.
    */
   public static long generateNewId() {
      return System.currentTimeMillis();
   }
}

使用PowerMock,可以期待对IdGenerator.generateNewId()的调用,就像您告诉PowerMock准备IdGenerator类进行测试一样,使用EasyMock的任何其他方法。您可以通过向类级别的测试用例添加注释来完成此操作。这只是使用@PrepareForTest(IdGenerator.class)完成的。您还需要告诉JUnit使用PowerMock执行测试,这是通过使用@RunWith(PowerMockRunner.class)完成的。没有这两个注释,测试就会失败。

实际测试实际上非常简单:

@Test
public void testRegisterService() throws Exception {
        long expectedId = 42;

        // We create a new instance of test class under test as usually.
        ServiceRegistartor tested = new ServiceRegistartor();

        // This is the way to tell PowerMock to mock all static methods of a
        // given class
        mockStatic(IdGenerator.class);

        /*
         * The static method call to IdGenerator.generateNewId() expectation.
         * This is why we need PowerMock.
         */
        expect(IdGenerator.generateNewId()).andReturn(expectedId);

        // Note how we replay the class, not the instance!
        replay(IdGenerator.class);

        long actualId = tested.registerService(new Object());

        // Note how we verify the class, not the instance!
        verify(IdGenerator.class);

        // Assert that the ID is correct
        assertEquals(expectedId, actualId);
}

请注意,即使类是final,也可以在类中模拟静态方法。该方法也可以是最终的。要仅模拟类的特定静态方法,请参阅文档中的部分模拟部分。

Reference: powermock wiki

答案 1 :(得分:0)

如果两个函数都在同一个类中,那么只需不使用任何对象或类名称即可调用。如果它们使用不同的函数,那么使用类名可以互相调用。希望这对您有所帮助。 :)