mock mvc a testy kontrolera

0

Mam taki kod w swoim kontrolerze:

   @GetMapping
    public ModelAndView getBooks() {
        ModelAndView mav = new ModelAndView("book_list");
        mav.addObject("books", bookService.findAll());
        Account account = accountService.authenticateUser();
        if (account != null) {
            if (accountService.isAdmin(account)) {
                mav.addObject("role", "ADMIN");
            } else {
                mav.addObject("role", "USER");
            }
        }
        return mav;
    }

oraz napisałem do tego takie testy:

    @Test
    public void testGetBooks() throws Exception {
        List<Book> books = new ArrayList<>();
        books.add(new Book("Paula Hawkins", "Dziewczyna z pociągu", "9781594633669", "angielski", 320, new BookQuantity(3)));
        books.add(new Book("Gillian Flynn", "Zaginiona dziewczyna", "9788377787915", "polski", 652, new BookQuantity(2)));

        when(bookService.findAll()).thenReturn((List) books);

        mockMvc.perform(get("/books"))
                .andExpect(view().name("book_list"))
                .andExpect(model().attribute("books", hasSize(2)));
    }

    @Test
    public void testGetBookAdmin() throws Exception {
        Account account = new Account("admin", "$2a$10$EblZqNptyYvcLm/VwDCVAuBjzZOI7khzdyGPBr08PpIi0na624b8.", true);
        when(accountService.getDistinctRoles()).thenReturn(new HashSet<String>(){{
            add("ADMIN");
        }});
        when(accountService.authenticateUser()).thenReturn(account);
        when(accountService.isAdmin(account)).thenReturn(true);
        mockMvc.perform(get("/books"))
                .andExpect(model().attributeExists("role"))
                .andExpect(model().attribute("role", "ADMIN"));
    }

    @Test
    public void testGetBookUserNotLogged() throws Exception {
        when(accountService.authenticateUser()).thenReturn(null);
        mockMvc.perform(get("/books"))
                .andExpect(model().attributeDoesNotExist("role"));
    }
  1. Czy takie testy są poprawne?
  2. Jeśli w tej metodzie getBooks mam kilka możliwość tzn. account może być null (użytkownik nie jest zalogowany) lub w zależności od rodzaju użytkownika dodaje atrybut "role". Czy 1 test powinien pokrywać całą metodę czy może być do tego kilka testów jak powyżej?
1

Te testy w sumie nic nie sprawdzają. Konfigurujesz środowisko pod konkretny element w ifie i sprawdzasz, czy ten if w ogóle działa... trochę takie testowanie języka tu widzę.

Proponuję podejść inaczej do problemu. Napisz testy integracyjne, w których na początku uruchomiony będzie skrypt, wypełniający bazę danych informacjami. Następnie test będzie sprawdzał kompleksowo cały przepływ, tzn. logował się do aplikacji, wybierał dane i weryfikował rezultat.

0

Właśnie @Koziołek ma racje.
Możesz napisać testy integracyjne kontrolera w których wywołujesz requesty. Korzystasz wtedy w dobrodziejstw IoC i np. zamiast bazy danych "normalnej" ładujesz dane z in memory database,
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/integration-testing.html

1 użytkowników online, w tym zalogowanych: 0, gości: 1