Spring Boot - Test for controller fails with 404 code

I am not sure why your test is not working. But I got another solution which works for me.

@SpringBootTest
public class ControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Before
    public void setup() {
        this.mockMvc = MockMvcBuilders.standaloneSetup(new TestController()).build();
    }

    @Test
    public void shouldReturnCorrectStation() throws Exception {
        mockMvc.perform(get("/stations")
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk());
    }
}

HTTP code 404, means no resource found (on the server) for your request, which I think that your controller is not visible(let me say is not scanned) by spring boot.

A simple solution is scanning a parent package in MockConfig class, so spring can pick up all beans,

@ComponentScan(basePackages = "edu.lelyak") // assuming that's the parent package in your project

if you don't like this approach, you can add the controller's package name in basePackages

@ComponentScan(basePackages = {"edu.lelyak.controller","edu.lelyak.repository") 

BTW, you don't have to manually set up WeatherStationService in MockConfig class, Spring boot can inject a mock for you and automatically reset it after each test method, you should just declare it in your test class:

@MockBean
private IStationRepository stationRepository;

On the other hand, you should mock weatherService.getAllStations() before calling get("/stations") in your test method (as you're not running integration test), so you can do:

List<WeatherStation> myList = ...;
//Add element(s) to your list
 Mockito.when(stationService.getAllStations()).thenReturn(myList);

You can find more in :

  • Testing improvements in Spring Boot 1.4

  • Spring Boot features: Testing


I had the same issue. The controller was not getting picked up despite specifying it with @WebMvcTest(MyController.class). This meant all of its mappings were ignored, causing the 404. Adding @Import(MyController.class) resolved the issue, but I didn't expect the import to be necessary when I'm already specifying which controller to test.