如何undo/resetPowerMockito.mockStatic?
How to undo/reset PowerMockito.mockStatic?
假设我有以下 类
public class StaticClass {
public static void staticMethod() throws SomeException {
System.out.println("staticMethod");
}
private StaticClass() {
}
}
和
public class SomeClass {
public void someMethod() {
try {
StaticClass.staticMethod();
}catch(SomeException ex) {
System.out.println("SomeException occurred");
return;
}
System.out.println("SomeException didn't occur");
}
}
我正在测试
@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();
}
}
如何撤消静态 mocking/the 配置以抛出 SomeException
以便我可以在第二个 instance.someMethod()
中的 try-catch 块之后测试代码?
PowerMock: How to unmock a method? 不适用,因为没有模拟引用传递给 Mockito.reset
并且传递 StaticClass
会导致 java.lang.ClassCastException: java.lang.Class cannot be cast to org.mockito.internal.creation.bytebuddy.MockAccess
.
SomeException
只是扩展了 Exception
.
https://gitlab.com/krichter/powermock-undo-statik-mocking 提供了 SSCCE。
我正在使用 PowerMock 1.7.3。
我的意见,但一般来说,单元测试应该使用单一代码路径。 (我认为这是将单一职责应用于测试方法。)
Bu 我关于拆分测试的建议确实解决了问题。我不知道细节,但是@PrepareForTest 为每个测试.
提供了一个新的 StaticClass
这些单独的测试有效:
@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。对于那些讨厌的私人静态最终记录器...
有一个 issue(参见 Karl 在接受的解决方案中的评论)解决它,解决方案是在方法级别使用 @PrepareForTest。
所以在你的测试方法中你需要注释
/*
* 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 装饰器放在 class 而不是方法
上
假设我有以下 类
public class StaticClass {
public static void staticMethod() throws SomeException {
System.out.println("staticMethod");
}
private StaticClass() {
}
}
和
public class SomeClass {
public void someMethod() {
try {
StaticClass.staticMethod();
}catch(SomeException ex) {
System.out.println("SomeException occurred");
return;
}
System.out.println("SomeException didn't occur");
}
}
我正在测试
@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();
}
}
如何撤消静态 mocking/the 配置以抛出 SomeException
以便我可以在第二个 instance.someMethod()
中的 try-catch 块之后测试代码?
PowerMock: How to unmock a method? 不适用,因为没有模拟引用传递给 Mockito.reset
并且传递 StaticClass
会导致 java.lang.ClassCastException: java.lang.Class cannot be cast to org.mockito.internal.creation.bytebuddy.MockAccess
.
SomeException
只是扩展了 Exception
.
https://gitlab.com/krichter/powermock-undo-statik-mocking 提供了 SSCCE。
我正在使用 PowerMock 1.7.3。
我的意见,但一般来说,单元测试应该使用单一代码路径。 (我认为这是将单一职责应用于测试方法。)
Bu 我关于拆分测试的建议确实解决了问题。我不知道细节,但是@PrepareForTest 为每个测试.
提供了一个新的 StaticClass这些单独的测试有效:
@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。对于那些讨厌的私人静态最终记录器...
有一个 issue(参见 Karl 在接受的解决方案中的评论)解决它,解决方案是在方法级别使用 @PrepareForTest。
所以在你的测试方法中你需要注释
/*
* 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 装饰器放在 class 而不是方法
上