【问题标题】:Spring boot mocking static methods with PowerMock in Integration testSpring Boot 在集成测试中使用 PowerMock 模拟静态方法
【发布时间】:2018-03-18 13:27:46
【问题描述】:

我正在 SpringBoot 中的 RestController 上编写集成测试。 通常我会使用 SpringRunner.class 运行,但是当涉及到 Mock 静态方法时,我需要使用 PowerMock。

奇怪的事实是,当我运行单个测试时,它们单独通过(但返回错误消息),当我尝试运行整个测试类时,没有测试通过并且返回相同的错误消息。

@RunWith(PowerMockRunner.class)
@PrepareForTest({JwtUtils.class})
//@PowerMockRunnerDelegate(SpringRunner.class) THIS DOESN'T WORK!!!
@SpringBootTest(classes = SpringBootJwtApplication.class)
public class RestAccessIntegrationTest {

  @Autowired @InjectMocks
  RestController restController;

  @Mock
  HttpServletRequest request;

  @Test
  public void operationsPerAccountWhenSuccessfulTest(){
    mockStatic(JwtUtils.class);
    when(JwtUtils.myMethod(request)).thenReturn("blabla");
    String expected = ... ;
    String actual = restController.getOperations();
    assertEquals(actual, expected);
  }

}

如果我运行测试或整个类,我会收到这种类型的错误:

线程“主”java.lang.NoSuchMethodError 中的异常:org.powermock.core.MockRepository.addAfterMethodRunner(Ljava/lang/Runnable;)at org.powermock.api.mockito.internal.mockcreation.MockCreator.mock(MockCreator .java:50)

如果我取消注释 @PowerMockRunnerDelegate(SpringRunner.class) 会出现另一个错误:

线程“主”java.lang.NoClassDefFoundError 中的异常:org/powermock/core/testlisteners/GlobalNotificationBuildSupport$Callback 在 org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner.run(DelegatingPowerMockRunner.java:139)

【问题讨论】:

    标签: unit-testing spring-boot junit mockito powermock


    【解决方案1】:

    when 方法中,尝试使用any(HttpServletRequest.class) 而不是request 模拟对象。也使用MockHttpServletRequest 而不是模拟HttpServletRequest。这应该可行,

    @RunWith(PowerMockRunner.class)
    @PrepareForTest(JwtUtils.class)
    @PowerMockIgnore( {"javax.management.*"})
    public class RestAccessIntegrationTest {
    
        @InjectMocks
        private RestController restController;
    
        private MockHttpServletRequest request;
    
        @Before
        public void setUp() {
            MockitoAnnotations.initMocks(this);
            request = new MockHttpServletRequest();
            RequestContextHolder.setRequestAttributes(
                    new ServletRequestAttributes(request));
        }
    
        @Test
        public void operationsPerAccountWhenSuccessfulTest() {
            mockStatic(JwtUtils.class);
            when(JwtUtils.myMethod(any(HttpServletRequest.class)))
               .thenReturn("blabla");
    
            String expected = ... ;
            // does your getOperations take HttpServletRequest
            // as parameter, then controller.getOperations(request);
            String actual = restController.getOperations();
            assertEquals(actual, expected);
        }
    }
    

    【讨论】:

    • 你还在用@SpringBootTest(classes = SpringBootJwtApplication.class)吗?我不使用的时候没有出现异常。
    • 我试过有无...我已经使用了你给我的所有说明。奇怪的是,每个单独的测试都有效,而整个班级都没有。
    【解决方案2】:

    这是由于 PowerMock 和 Mockito 的库版本不兼容。建议查看 PowerMock 团队提供的兼容性版本表,或者切换到 JMockit 来模拟静态和私有方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-28
      • 2014-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-09
      • 1970-01-01
      相关资源
      最近更新 更多