How to undo/reset PowerMockito.mockStatic?
假设我有以下课程
1 2 3 4 5 6 7 8 9 | public class StaticClass { public static void staticMethod() throws SomeException { System.out.println("staticMethod"); } private StaticClass() { } } |
和
1 2 3 4 5 6 7 8 9 10 11 12 |
我正在测试的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | @RunWith(PowerMockRunner.class) @PrepareForTest(StaticClass.class) public class SomeClassTest { @Test public void testStaticMethod() throws Exception { mockStatic(StaticClass.class); doThrow(new SomeException("unimportant message")).when(StaticClass.class, "staticMethod"); //test something where exception is needed SomeClass instance = new SomeClass(); try { instance.someMethod(); fail("IllegalStateException expected"); }catch(IllegalStateException expected) { } //now test something where exception isn't needed instance.someMethod(); } } |
如何撤消静态模拟/配置以抛出
PowerMock:如何取消模拟方法?不适用,因为没有模拟引用传递给
在https://gitlab.com/krichter/powermock-undo-statik-mocking上提供了SSCCE。
我正在使用PowerMock 1.7.3。
我的看法是,但总体而言,单元测试应使用一条代码路径。 (我认为这是对测试方法应用单一职责。)
我关于拆分测试的建议确实可以解决问题。我不知道详细信息,但是@PrepareForTest为每个测试提供了一个新的StaticClass。
这些单独的测试有效:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | @Test public void testStaticMethodWhenSomethingUnexpectedHappens() throws Exception { mockStatic(StaticClass.class); // changed exception type doThrow(new IllegalStateException("unimportant message")).when(StaticClass.class,"staticMethod"); SomeClass instance = new SomeClass(); try { instance.someMethod(); fail("IllegalStateException expected"); } catch (IllegalStateException expected) { } // added verification verifyStaticMethodWasInvokedOneTime(); } @Test public void testStaticMethodHappyPath() throws Exception { mockStatic(StaticClass.class); doNothing().when(StaticClass.class,"staticMethod"); SomeClass instance = new SomeClass(); instance.someMethod(); // added verification verifyStaticMethodWasInvokedOneTime(); } private void verifyStaticMethodWasInvokedOneTime() throws SomeException { verifyStatic(StaticClass.class); StaticClass.staticMethod(); } |
对于任何想知道如何重置PowerMocks e.x的人。对于那些讨厌的私人静态最终记录器...
存在一个问题(请参见接受的解决方案中的Karl的评论),解决方案是在方法级别使用@PrepareForTest。
因此在您的测试方法中,需要注释
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | /* * Test for MyClass.java which uses a private static final logger */ public class MyStaticMockTest { static final Logger logger = PowerMockito.mock(Logger.class); @BeforeClass public static void setup() { PowerMockito.mockStatic(LoggerFactory.class); PowerMockito.when(LoggerFactory.getLogger(MyClass.class)) .thenReturn(MyStaticMockTest.logger); } @Test @PrepareForTest({LoggerFactory.class, Logger.class}) public void testit() { MyClass mc = new MyClass(); mc.methodWithSomeLogging(); Mockito.verify(MyStaticMockTest.logger).info("some message"); } @Test @PrepareForTest({LoggerFactory.class, Logger.class}) public void testit() { MyClass mc = new MyClass(); mc.anotherMethodWithSomeLoggingButUsingSameMessage(); //Method will pass and not complain about info being called 2x Mockito.verify(MyStaticMockTest.logger, Mockito.times(1)).info("some message"); } } |
如果要重置每个方法,只需将@PrepareForTest装饰器放在类上,而不是方法上