代码之家  ›  专栏  ›  技术社区  ›  Michael Coxon

带有效请求的Spring Boot MVC测试404

  •  0
  • Michael Coxon  · 技术社区  · 7 年前

    @Secured("ROLE_ADMIN")
    @GetMapping(value = {"/maintainers/aircrafts/workorders/workitems/{wid}/parts"}, produces = "application/json")
    @ResponseStatus(value = HttpStatus.OK)
    Response<Page<WorkItem>> getPagedParts(
            @PathVariable("wid") Optional<Long> 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));
    }
    

    如您所见,它应该进行分页和排序,但它甚至不能通过路径:

    测试它的测试如下:

    @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<WorkSet> sets = contract.getWorkOrders().stream().findFirst().get().getWorkSets();
    
            WorkSet hundredHourly = sets.stream().filter(s -> s.getName().equals("100 Hourly for PA-31")).findFirst().orElse(null);
    
            WorkItem opening = hundredHourly.getWorkItems().stream().filter(wi -> 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);
        }
    }
    

    由于该项目广泛使用了JPA,因此有注释和大量的数据设置,但是所有这些在其他测试中都工作得很好,而且数据似乎没有任何问题。事实上,这个方法应该查询的工单的JSON输出是一个很好的例子。。。

    work order JSON

    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<org.springframework.data.domain.Page<au.com.avmaint.api.aircraft.model.WorkItem>> au.com.avmaint.api.aircraft.WorkItemController.getPagedParts(java.util.Optional<java.lang.Long>,org.springframework.data.domain.Pageable)
    

    所以路径看起来没问题

    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 = <no character encoding set>
        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 = []
    

    还有404。所以我想我在什么地方弄坏了什么东西,我就是看不出来是什么东西,有人能帮忙吗?

    1 回复  |  直到 7 年前
        1
  •  0
  •   Michael Coxon    7 年前

    抱歉,各位,把我的头发扯了好长时间,终于把问题贴出来了,一会儿又发现了问题。

    /api 作为测试中路径上的前缀。此前缀放在每个控制器的顶部,带有:

    @RestController
    @RequestMapping("/api")
    public class WorkItemController {