首页 > 解决方案 > 具有有效请求的 Spring Boot MVC 测试 404

问题描述

我正在使用 Spring Boot 2.0.6 并为控制器设置了测试:方法如下:

@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 输出......

工单 JSON

基本上已经正确设置了所有数据。spring boot 启动包括这一行:

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)

所以路径似乎没问题

现在到 .andDo(print()) 输出:

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。所以我想我在某个地方弄坏了一些东西,我只是看不到它是什么,有人可以帮忙吗?

标签: spring-mvcspring-bootspring-data-jpaspring-data-restspring-boot-test

解决方案


对不起大家,把我的头发扯了好久的效果,终于发布了问题,然后过了一会儿才发现问题。

问题是我忘记/api在测试中的路径上添加前缀。这个前缀放在每个控制器的顶部:

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

所以,是的:它现在有效


推荐阅读