How to mock some beans but not others in MockMVC?

Viewed 3357

I'm trying to write a unit test for a controller. Some of the dependencies (such as a service class) I'm mocking with @MockBean. But there are other dependencies I want to just have spring create the beans as usual. Is this possible?

@RunWith(SpringRunner.class)
@WebMvcTest(JwtAuthenticationController.class)
public class JwtControllerTests {

    @MockBean
    private JwtUserDetailsService jwtUserDetailsService;

    @MockBean
    private AuthenticationManager authenticationManager;

    @ ? ? ?
    private JwtTokenUtil jwtTokenUtil

    public void auth_Success() throws Exception {
        when(
            jwtUserDetailsService.loadUserByUsername(anyString())
        ).thenReturn(adminUserDetails);

        RequestBuilder request = MockMvcRequestBuilders
            .post("/api/v1/authenticate")
            .contentType(MediaType.APPLICATION_JSON)
            .content(authBody);
    }
}

Controller code:

public class JwtAuthenticationController {
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private JwtUserDetailsService jwtUserDetailsService;
}
2 Answers

You have @WebMvcTest.

Annotation that can be used for a Spring MVC test that focuses only on Spring MVC components.

You need to use @SpringBootTest(classes = Application.class) and configure your MockMvc.

@RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
public class JwtControllerTests {

    private MockMvc mockMvc;


    @MockBean
    private JwtUserDetailsService jwtUserDetailsService;

    @MockBean
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;


    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        this.mockMvc = MockMvcBuilders.standaloneSetup(new JwtAuthenticationController(authenticationManager,jwtUserDetailsService,jwtTokenUtil))
                .addInterceptors(interceptor)
                .setControllerAdvice(exceptionTranslator)
                .build();
    }

    @Test
    public void auth_Success() throws Exception {
        when(
                jwtUserDetailsService.loadUserByUsername(anyString())
        ).thenReturn(adminUserDetails);

        RequestBuilder request = MockMvcRequestBuilders
                .post("/api/v1/authenticate")
                .contentType(MediaType.APPLICATION_JSON)
                .content(authBody);

         mockMvc.perform(request).andExpect(status().isOk());
    }
}

Change your JwtAuthenticationController to accept dependencies by the constructor.

you can @SpyBean

@SpyBean
private JwtTokenUtil jwtTokenUtil
Related