@MaxLich
java developer

Почему при тесте реста выдаёт 404?

Здравствуйте. Имеется контроллер:
spoiler
**
 * REST-контроллер для непосредственной работы с активити
 */
@Controller
@RequestMapping(value = "/process", produces = {"application/json"})
public class ActivitiController {
    private static final Logger logger = LogManager.getLogger(ActivitiController.class);

    private final ActivitiService activitiService;

    @Autowired
    public ActivitiController(ActivitiService activitiService) {
        this.activitiService = activitiService;
    }

    /**
     * Стартует процесс в активити
     *
     * @param processName имя процесса, который нужно стартовать
     * @param params      параметры, передаваемые при старте процесса
     * @return идентификатор экземпляра процесса, созданного после старта процесса
     */
    @PostMapping(value = "/start")
    @ResponseBody
    public String startProcess(@RequestParam("processName") String processName, @RequestBody Map<String, String> params ) {
        Map<String, Object> variables = new HashMap<>();
        params.forEach(variables::put);

        ProcessInstance newProcessInstance = null;
        try {
            newProcessInstance = activitiService.startProcess(processName, variables);
        } catch (ActivitiServiceException e) {
            logger.warn(e);
            return "null";
        }
        return newProcessInstance.getProcessInstanceId();
    }
}

Хочу протестировать метод startProcess()в этом классе.
Написал юнит-тест:
spoiler
@RunWith(SpringRunner.class)
@WebMvcTest(value = ActivitiController.class, secure = false)
public class ActivitiControllerTests {

    private static final String TEST_PROCESS_NAME = "process_name";
    private static final String TEST_PROCESS_INSTANCE_ID = "12";
    private static final String TEST_TASK_INSTANCE_ID = "14";

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private ActivitiService activitiService;
    private ProcessInstance getTestProcessInstance() {
        return new ProcessInstance() {
            @Override
            public String getProcessInstanceId() {
                return TEST_PROCESS_INSTANCE_ID;
            }
       };
    }

    @Test
    public void testStartProcess() throws Exception {
        given(activitiService.startProcess(TEST_PROCESS_NAME, Collections.emptyMap()))
                .willReturn(getTestProcessInstance());

        mockMvc.perform(
                post("/process/start")
                        .param("processName", TEST_PROCESS_NAME)
                        .contentType(MediaType.APPLICATION_JSON)
                        .accept(MediaType.APPLICATION_JSON)
                        .content("{\"key\":\"value\"}"))
                .andDo(print())
                .andExpect(status().isOk());
    }
}

После запуска выдаёт код ответа 404, вместо кода 200.
До этого другая была ошибка (
java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...)

), и для этого я положил пустую конфигурацию на уровень выше в дереве каталогов:
5c51cbe4ba0dd717144365.png
@SpringBootConfiguration
public class FakeConfig {}


Такая информация показывается в консоли:
spoiler
MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /process/start
       Parameters = {processName=[process_name]}
          Headers = {Content-Type=[application/json], Accept=[application/json]}
             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 = {}
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /process/start
       Parameters = {processName=[process_name]}
          Headers = {Content-Type=[application/json], Accept=[application/json]}
             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 = {}
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

java.lang.AssertionError: Status 
Expected :200
Actual   :404
 <Click to see difference>


Если делаю, как в примере ссылка, то есть добавляю на уровень выше класс:
@SpringBootApplication
public class DemoApplication {

    public static void main(String... args){
        SpringApplication.run(DemoApplication.class);
    }
}


то выдаёт:
spoiler

MockHttpServletRequest:
HTTP Method = POST
Request URI = /process/start
Parameters = {processName=[process_name]}
Headers = {Content-Type=[application/json], Accept=[application/json]}
Body =
Session Attrs = {}

Handler:
Type = ru.cip.rlic.core.api.controller.rest.ActivitiController
Method = public java.lang.String ru.cip.rlic.core.api.controller.rest.ActivitiController.startProcess(java.lang.String,java.util.Map)

Async:
Async started = false
Async result = null

Resolved Exception:
Type = null

ModelAndView:
View name = null
View = null
Model = null

FlashMap:
Attributes = null

MockHttpServletResponse:
Status = 200
Error message = null
Headers = {Content-Type=[application/json;charset=UTF-8], Content-Length=[4]}
Content type = application/json;charset=UTF-8
Body = null
Forwarded URL = null
Redirected URL = null
Cookies = []

MockHttpServletRequest:
HTTP Method = POST
Request URI = /process/start
Parameters = {processName=[process_name]}
Headers = {Content-Type=[application/json], Accept=[application/json]}
Body =
Session Attrs = {}

Handler:
Type = ru.cip.rlic.core.api.controller.rest.ActivitiController
Method = public java.lang.String ru.cip.rlic.core.api.controller.rest.ActivitiController.startProcess(java.lang.String,java.util.Map)

Async:
Async started = false
Async result = null

Resolved Exception:
Type = null

ModelAndView:
View name = null
View = null
Model = null

FlashMap:
Attributes = null

MockHttpServletResponse:
Status = 200
Error message = null
Headers = {Content-Type=[application/json;charset=UTF-8], Content-Length=[4]}
Content type = application/json;charset=UTF-8
Body = null
Forwarded URL = null
Redirected URL = null
Cookies = []

java.lang.AssertionError: Response content
Expected :12
Actual :null


Добавление DemoApplicationвроде бы помогает. Но потом падает на проверке возвращаемого значения. Если в проверяемый метод кидать any(), то всё проходит. Но как сделать, чтобы без any() работало, не знаю.
  • Вопрос задан
  • 711 просмотров
Решения вопроса 1
@MaxLich Автор вопроса
java developer
Помог пример из статьи
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
EreminD
@EreminD
Кое-что умею
вы делаете post("/process/start")
А где объявляется часть пути /process?

Если сделать
@RestController
@RequestMapping("/process")
public class ActivitiController {

   @PostMapping(value = "/start")
   public String startProcess(@RequestParam("processName") String processName, @RequestBody Map<String, String> params ) {
        ...
    }
}

будет работать?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы