Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring boot jUnit test fails because of "org.springframework.beans.factory.NoSuchBeanDefinitionException"

Tags:

java

spring

I'm writing an end-to-end test for the following class in my Spring boot project, but I receive org.springframework.beans.factory.NoSuchBeanDefinitionException error because No qualifying bean of type 'com.boot.cut_costs.service.CustomUserDetailsService' available.

@RestController
public class AuthenticationController {

    @Autowired
    protected AuthenticationManager authenticationManager;
    @Autowired
    private CustomUserDetailsService userDetailsServices;
    @Autowired
    private UserDetailsDtoValidator createUserDetailsDtoValidator;

    @RequestMapping(value = "/signup", method = RequestMethod.POST)
    public void create(@RequestBody UserDetailsDto userDetailsDTO, HttpServletResponse response, BindingResult result) {
        // ...
        userDetailsServices.saveIfNotExists(username, password, name);
        // ...
        if (authenticatedUser != null) {
            AuthenticationService.addAuthentication(response, authenticatedUser.getName());
            SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
        } else {
            throw new BadCredentialsException("Bad credentials provided");
        }
    }
}

Test class:

@RunWith(SpringRunner.class)
@WebMvcTest(AuthenticationController.class)
public class AuthenticationControllerFTest {

    @Autowired 
    private MockMvc mockMvc;

    @MockBean
    private AuthenticationManager authenticationManager;

    @Test
    public void testCreate() throws Exception {
        Authentication authentication = Mockito.mock(Authentication.class);
        Mockito.when(authentication.getName()).thenReturn("DUMMY_USERNAME");
        Mockito.when(
                authenticationManager.authenticate(Mockito
                    .any(UsernamePasswordAuthenticationToken.class)))
                .thenReturn(authentication);

        //....
        RequestBuilder requestBuilder = MockMvcRequestBuilders
                .post("/signup")
            .accept(MediaType.APPLICATION_JSON).content(exampleUserInfo)
                .contentType(MediaType.APPLICATION_JSON);

        MvcResult result = mockMvc.perform(requestBuilder).andReturn();

        MockHttpServletResponse response = result.getResponse();
    }
}

I think this error happens because it in the test environment the spring context isn't loaded the same way as in dev/production environment. How should I fix this issue ?

Edit 1

My Spring boot application entry point is App.java:

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}
like image 807
Arian Avatar asked Oct 31 '25 15:10

Arian


2 Answers

@WebMvcTest only loads the controller configuration. That's why you had this DI error (with it, you have to provide mocks for your services). So, if you need to inject your services, you can use @SpringBootTest.

If you use @SpringBootTest, you also have to use @AutoConfigureMockMvcto configure MockMvc.

like image 115
Thoomas Avatar answered Nov 03 '25 05:11

Thoomas


You need to pull in the configuration which does the component scanning for your beans using @ContextConfiguration annotation on your test class.

This could potentially load configuration that is not needed or may even cause the tests to fail so a safer way to do it would be to write a configuration class yourself with only what you need to get the test to run (potentially just the relevant component scan for your beans). If you write this config class as a static inner class of your test class then you can pull this config in by just using the @ContextConfiguration annotation with no parameters.

@ContextConfiguration
public class MyTestClass {

   @Test
   public void myTest() {
     ...
   }

   @Configuration
   @ComponentScan("my.package")
   public static class MyTestConfig {
   }
like image 27
Plog Avatar answered Nov 03 '25 06:11

Plog



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!