1

So I have a couple Tests that run using mockito. One requires a static to be mocked so I use PowerMockito like this...

BDDMockito.given(WebClient.create(any())).willReturn(webClientMock);

Next I have another test that mocks a final class like this...

HttpSecurity security = Mockito.mock(HttpSecurity.class);

The second one doesn't work at first, I get the following failure....

Cannot mock/spy class org.springframework.security.config.annotation.web.builders.HttpSecurity
Mockito cannot mock/spy because :
 - final class

So I looked and found this question which suggests adding the file .../src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker with mock-maker-inline

But when I add that the first line fails with...

org.mockito.exceptions.misusing.NotAMockException: Argument should be a mock, but is: class java.lang.Class

How do I get both to work?

Update

I didn't want to clutter up the question with the entire test which really doesn't provide any extra context. However, since people are insisting and seem to misunderstand the question...

// Static

@ExtendWith(MockitoExtension.class)
@RunWith(PowerMockRunner.class)
@PrepareForTest(WebClient.class)
public class RasaServiceTest {
    @Mock
    private WebClient webClientMock;
    @Mock
    private WebClient.RequestHeadersSpec requestHeadersMock;
    @Mock
    private WebClient.RequestHeadersUriSpec requestHeadersUriMock;
    @Mock
    private WebClient.RequestBodyUriSpec requestBodyUriMock;
    @Mock
    private WebClient.ResponseSpec responseMock;

    private MyService service = new MyService();

    @BeforeAll
    public void setup(){
        PowerMockito.mockStatic(WebClient.class);
        BDDMockito.given(WebClient.create(any())).willReturn(webClientMock);
    }
    @Test
    public void HappyPath(){
        MessageResponseItem item = new MessageResponseItem();
        item.setRecipientId("id");
        item.setResponseText("response");
        MessageResponseItem[] items = {item};
        when(webClientMock.post()).thenReturn(requestBodyUriMock);
        when(requestHeadersUriMock.uri("/webhooks/rest/webhook")).thenReturn(requestHeadersMock);
        when(requestHeadersMock.retrieve()).thenReturn(responseMock);
        when(responseMock.bodyToMono(MessageResponseItem[].class)).thenReturn(Mono.just(items));
        InferenceEngineRequest request = new InferenceEngineRequest();
        MessageResponseItem[] result = service.call(request).block();
        assertThat(result.length).isEqualTo(1);
        assertThat(result[0].getResponseText()).isEqualTo("response");
    }
}

// Final

@RunWith(MockitoJUnitRunner.class)
public class RemoveMeConfigTest {
    @Test
    public void happyPath() throws Exception {
        HttpSecurity security = Mockito.mock(HttpSecurity.class);
        CsrfConfigurer<HttpSecurity> csrf = Mockito.mock(CsrfConfigurer.class);
        RemoveMeConfig config = new RemoveMeConfig();
        Mockito.when(
                security.csrf()
        ).thenReturn(csrf);
        Mockito.when(
                csrf.disable()
        ).thenReturn(security);
        config.configure(security);
        Mockito.verify(
                security,
                Mockito.times(
                        1
                )
        ).csrf();
        Mockito.verify(
                csrf,
                Mockito.times(1)
        ).disable();
    }
}
JGleason
  • 3,067
  • 6
  • 20
  • 54
  • I hope you're using a PowerMockRunner for running your test. In addition that, did you prepare the class with `@PrepareForTest(Employee.class)` before mocking methods with PowerMock ? – Arkantos Nov 03 '20 at 14:04
  • 1
    You don't. Doing this is a bad practice that will make the test maintenance suffer. One important practice of using mocks is *don't mock types you don't own*. Another bad practice (which looks you might be doing) is that mocks shouldn't return other mocks. If you are writing your code using a 'chicago' TDD approach, avoid using mocks (google *chicago london TDD*). – Augusto Nov 03 '20 at 15:11
  • @GhostCat I think you misunderstand PowerMockito works just not when I add the inline stuff. – JGleason Nov 03 '20 at 15:17
  • @Arkantos yes both of those are there – JGleason Nov 03 '20 at 15:18
  • 2
    Full test added but these comments don't seem to understand what I am trying to do. I have 2 tests one that needs to mock a final class one that needs to mock a static method. These other comments (Except @Augusto which has fair criticism even if it doesn't answer the question) seem to think the PowerMock test doesn't work. It does, just not with the additional configuration for the second one. This is not a problem with PowerMockito "not working" just not working with mock-maker-inline. Thanks to everyone for trying to help though – JGleason Nov 03 '20 at 15:25
  • @Augusto I reread your response, at the end of the day I just need to mock Spring and I figured the easiest way was to Mock the HttpSecurity class. But let me rethink. Maybe I can just using the "@SpringBootTest" annotation – JGleason Nov 13 '20 at 16:12

0 Answers0