#java #spring-boot #spring-mvc #junit
#java #весенняя загрузка #spring-mvc #junit
Вопрос:
Я объявил интерфейс как свойство моего @RestController
. В этом интерфейсе всего несколько полей / установщиков / получателей.
Реализация RestController и GetMapping выглядят следующим образом:
@RestController
@EnableAutoConfiguration
public class AccountController {
private AccountStoreInterface store;
@GetMapping(value="/account")
public Account readAccount(@RequestParam("id") String id) throws AccountNotFoundException {
Account a = store.getAccount(id);
if (a.getId().isEmpty()) {
throw new AccountNotFoundException();
}
return a;
}
@ExceptionHandler(AccountNotFoundException.class)
@ResponseStatus(NOT_FOUND)
public @ResponseBody String handleAccountNotFoundException(AccountNotFoundException ex) {
return ex.getMessage(); }
@ExceptionHandler(NullPointerException.class)
@ResponseStatus(INTERNAL_SERVER_ERROR)
public @ResponseBody String handleNullPointerException(NullPointerException ex) {
return ex.getMessage();
}
}
Объявление интерфейса выглядит следующим образом:
public interface AccountStoreInterface {
public Account getAccount(String id) throws AccountNotFoundException;
public Account setAccount(String id, Account account) throws AccountConflictException;
}
Я хотел бы протестировать это с помощью spring-boot-starter-test
и junit4
. Я ожидаю, что следующий тест вернет 500, потому что я не передал ни одного объекта store, который реализует мой интерфейс, поэтому он должен выдавать NullPointerException
.
Как мне настроить мои модульные тесты, чтобы протестировать 500
и 404
коды состояния?
Прямо сейчас приведенный ниже тест фактически завершается неудачей, потому что возвращенный статус равен 200, который я не понимаю, как junit получает.
@RunWith(SpringRunner.class)
@WebMvcTest(AccountController.class)
public class TestAccountController {
@Autowired private MockMvc mockMvc;
@Autowired private WebApplicationContext wac;
@MockBean
private AccountController accountController;
@Test
public void testGetAccountNotFound() throws Exception {
mockMvc.perform(get("/account?id={id}", "test-account-id-123")
.accept(APPLICATION_JSON)
.characterEncoding("UTF-8"))
.andDo(print())
.andExpect(status().isNotFound());
}
}
Комментарии:
1. Начните с удаления поля wac (вы его нигде не используете) и поля AccountController (вы его нигде не используете, и оно не должно быть макетным компонентом: вы хотите протестировать свой реальный контроллер, а не макет контроллера). Вы не должны ожидать 404: ресурс действительно существует, вы должны ожидать ошибку 500 из-за исключения NullPointerException. Но какой смысл тестировать код, который гарантированно будет неправильным?
2. Я просто действительно хочу объявить объект, который реализует хранилище моей учетной записи, а затем протестировать возвращенный JSON, но я не могу заставить его возвращать код состояния, который я ожидаю. Я только начал с Java и spring… тест для запроса GET должен начинаться с вставки чего-либо в хранилище, а затем я бы использовал MockMvc для выполнения запроса GET и проверки выходных данных. это то, что я пытаюсь сделать.
3. Прежде всего, уясните себе, что если вы пишете модульный тест или интеграционный тест, то, поскольку вы используете
Autowired
иSpringRunner
, он загружает ApplicationContext и, следовательно, является интеграционным тестом. Но вы тоже используетеMockBean
. Издевательство используется в модульном тестировании. Итак, исправьте эти вещи, а затем повторно запустите свои тесты.4. Почему это должно быть. Вы издеваетесь над своим контроллером, поэтому функциональность не вызывается. Вы должны издеваться над
AccountStoreInterface
вместо этого и@Autowire
контроллером.5. @M.Deinum это похоже на то, что я пытаюсь сделать. Я просто действительно сбит с толку всеми различными аннотациями и тем, что они делают. Исходя из другой среды, я нахожу это немного сложным. Спасибо за подсказку.