title: Spring Boot MVC Test 404 with Valid Request
body: <p>I am using Spring Boot 2.0.6 and have set up a test for a controller: the method is as follows:</p>
  
  <pre><code>@Secured("ROLE_ADMIN")
  @GetMapping(value = {"/maintainers/aircrafts/workorders/workitems/{wid}/parts"}, produces = "application/json")
  @ResponseStatus(value = HttpStatus.OK)
  Response&lt;Page&lt;WorkItem&gt;&gt; getPagedParts(
          @PathVariable("wid") Optional&lt;Long&gt; workItemId,
          @PageableDefault(page = DEFAULT_PAGE_NUMBER, size = DEFAULT_PAGE_SIZE)
          @SortDefault.SortDefaults({
                  @SortDefault(sort = "partName", direction = Sort.Direction.ASC),
                  @SortDefault(sort = "partSpecification", direction = Sort.Direction.ASC)
          }) Pageable pageable) {
      LOG.info("looking for work: {}", workItemId);
      return Response.of(workItemService.findAllPartsForWorkItem(workItemId.get(), pageable));
  }
  </code></pre>
  
  <p>As you can see, it is supposed to do paging and sorting, but it doesn't even get past the path:</p>
  
  <p>The test that tests it is as follows:</p>
  
  <pre><code>@ActiveProfiles("embedded")
  @RunWith(SpringRunner.class)
  @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
  @EnableConfigurationProperties
  @EnableJpaRepositories({ "au.com.avmaint.api" })
  @AutoConfigureMockMvc
  public class WorkItemControllerPartsFunctionalTest {
  
      private static final Logger LOG = LoggerFactory.getLogger(WorkItemControllerFunctionalTest.class);
  
      private String adminJwtToken;
  
      @Autowired
      private WebApplicationContext context;
  
      @Autowired
      private MockMvc mvc;
  
      @Autowired
      private UserService userService;
  
      @Autowired
      private RoleService roleService;
  
      @Autowired
      private CasaService casaService;
  
      @Autowired
      private MaintainerService maintainerService;
  
      @Autowired
      private MaintenanceContractService maintenanceContractService;
  
      @Autowired
      private WorkSetService workSetService;
  
      @Autowired
      private WorkSetTemplateService workSetTemplateService;
  
      @Autowired
      private AircraftService aircraftService;
  
      Maintainer franks;
      MaintenanceContract contract;
  
      @Before
      public void setup() {
          mvc = MockMvcBuilders
                  .webAppContextSetup(context)
                  .apply(springSecurity())
                  .build();
  
          franks = MaintainerFixtures.createFranksMaintainer(maintainerService, maintenanceContractService, casaService);
  
          adminJwtToken = UserAndRoleFixtures.adminToken(userService, roleService, franks);
  
          contract = WorkItemFixtures.makeDetailedJobOnContract(franks, maintainerService, maintenanceContractService, workSetTemplateService, casaService, aircraftService);
  
  
      }
  
      @Test
      public void findingWorkItemsWithoutParts() throws Exception {
  
          Set&lt;WorkSet&gt; sets = contract.getWorkOrders().stream().findFirst().get().getWorkSets();
  
          WorkSet hundredHourly = sets.stream().filter(s -&gt; s.getName().equals("100 Hourly for PA-31")).findFirst().orElse(null);
  
          WorkItem opening = hundredHourly.getWorkItems().stream().filter(wi -&gt; wi.getTitle().equals("Opening the aircraft")).findFirst().orElse(null);
  
          LOG.info("opening item: {}", opening);
  
          LOG.info("HUNDRED: {}", hundredHourly);
  
          mvc.perform(get("/maintainers/aircrafts/workorders/workitems/" + opening.getId() + "/parts")
                  .header(AUTHORIZATION_HEADER, "Bearer " + adminJwtToken))
                  .andDo(print())
                  .andExpect(status().isOk())
                  .andExpect(jsonPath("$.payload").isNotEmpty())
                  .andExpect(jsonPath("$.payload.content").isNotEmpty())
                  .andExpect(jsonPath("$.payload.pageable").isNotEmpty())
                  .andExpect(jsonPath("$.payload.last").value(false))
                  .andExpect(jsonPath("$.payload.totalPages").value(3))           // page count
                  .andExpect(jsonPath("$.payload.totalElements").value(9))       // total count
                  .andExpect(jsonPath("$.payload.size").value(4))                // elements per page
                  .andExpect(jsonPath("$.payload.numberOfElements").value(4))    // elements in page
                  .andExpect(jsonPath("$.payload.number").value(0))               // current page number
                  .andExpect(jsonPath("$.payload.content").isArray())
                  // oops, lets not check dates, they're created on the instant
                  .andExpect(jsonPath("$.payload.content[0].pos").value("1"))
                  .andExpect(jsonPath("$.payload.content[0].title").value("Opening the aircraft"))
                  .andExpect(jsonPath("$.payload.content[0].category").value("AIRFRAME"))
          ;
  
      }
  
      @After
      public void tearDown() {
  
          MaintainerFixtures.removeFranks(franks, maintainerService, aircraftService);
          WorkItemFixtures.killJobs(workSetService, workSetTemplateService);
          UserAndRoleFixtures.killAllUsers(userService, roleService);
      }
  }
  </code></pre>
  
  <p>As the project makes extensive use of JPA, there are annotations and a lot of data setup, but all of this has worked fine with other tests and there don't appear to be any problems with the data. In fact a peek at the JSON output for the work order that this method should be querying...</p>
  
  <p><a href="https://jsfiddle.net/rk345h8y/" rel="nofollow noreferrer">work order JSON</a></p>
  
  <p>Basically has all the data correctly set up. The spring boot startup includes this line:</p>
  
  <pre><code>2018-11-12 06:32:17.362  INFO 83372 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/api/maintainers/aircrafts/workorders/workitems/{wid}/parts],methods=[GET],produces=[application/json]}" onto au.com.avmaint.api.common.Response&lt;org.springframework.data.domain.Page&lt;au.com.avmaint.api.aircraft.model.WorkItem&gt;&gt; au.com.avmaint.api.aircraft.WorkItemController.getPagedParts(java.util.Optional&lt;java.lang.Long&gt;,org.springframework.data.domain.Pageable)
  </code></pre>
  
  <p>So the path appears to be OK</p>
  
  <p>and now to the .andDo(print()) output:</p>
  
  <pre><code>MockHttpServletRequest:
        HTTP Method = GET
        Request URI = /maintainers/aircrafts/workorders/workitems/5/parts
         Parameters = {}
            Headers = {Authorization=[Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJmcmFua0BmcmFua3MuY29tIiwic2NvcGVzIjpbIlJPTEVfQURNSU4iLCJST0xFX0JBU0lDIl0sImV4cCI6MTU0MjgyODczOH0.QOTiyWG_pVL9qb8MDG-2c_nkTnsIzceUH-5vvtmpZhBcdro9HqVADojK0-c6B1sAOOYOcprpwg4-wrBF0PGweg]}
               Body = &lt;no character encoding set&gt;
      Session Attrs = {}
  
  Handler:
               Type = org.springframework.web.servlet.resource.ResourceHttpRequestHandler
  
  Async:
      Async started = false
       Async result = null
  
  Resolved Exception:
               Type = null
  
  ModelAndView:
          View name = null
               View = null
              Model = null
  
  FlashMap:
         Attributes = null
  
  MockHttpServletResponse:
             Status = 404
      Error message = null
            Headers = {X-Content-Type-Options=[nosniff], X-XSS-Protection=[1; mode=block], Cache-Control=[no-cache, no-store, max-age=0, must-revalidate], Pragma=[no-cache], Expires=[0], X-Frame-Options=[DENY]}
       Content type = null
               Body = 
      Forwarded URL = null
     Redirected URL = null
            Cookies = []
  </code></pre>
  
  <p>and the 404. So I guess I'm breaking something somewhere, I just can't see what it is, can anyone help with this?</p>