lundi 9 septembre 2019

Spring Boot testing - NPE in controller when(...findAll()).thenReturn(something)

im starting to learn Spring Boot unit testing. I've created following test:

@RunWith(MockitoJUnitRunner.class)
public class UserControllerTests {

    @Autowired
    private MockMvc mockMvc;

    @Mock
    private UserRepository userRepository;

    @InjectMocks
    private UserController userController;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
    }

    @Test
    @WithMockUser(roles={"ADMIN"})
    public void should_gettingUsers_with_adminRole_return_allUsers() throws Exception {
        User testUser1 = new User("testuser1", "password1", "testuser", "testuser", new String[] {"ROLE_USER"});
        User testUser2 = new User("testuser2", "password1", "testuser", "testuser", new String[] {"ROLE_USER"});
        testUser1.setId(12345L);
        testUser1.setId(12346L);

        List <User> users = Arrays.asList(testUser1, testUser2);

        Mockito.when(userRepository.findAll()).thenReturn(users);

       mockMvc.perform(get("/api/v1/users"))
                .andExpect(status().isOk());
    }
}

which test UserController retrieveAllUsers method (when admin is logged in, it returns all users, when user is logged in, it returns only logged in user) returning user HATEOAS resources with links:

    @GetMapping(value= "/users" , produces = "application/json")
    @Secured({"ROLE_ADMIN", "ROLE_USER"})
    public Resources<Resource <User>> retrieveAllUsers() {
        Collection<? extends GrantedAuthority> authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities();
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        List <Resource <User>> users = new ArrayList <Resource<User>>();
        for (GrantedAuthority grantedAuthority : authorities) {
            if (grantedAuthority.getAuthority().equals("ROLE_USER")) {
                String username;
                username = ((UserDetails)principal).getUsername();
                Optional <User> user = userRepository.findByUsername(username);
                Resource <User> userResource = userResourceAssembler.toResource(user.get());
                users.add(userResource);
            } else if (grantedAuthority.getAuthority().equals("ROLE_ADMIN")) {

                users = userRepository.findAll().stream()
                        .map(userResourceAssembler::toResource)
                        .collect(Collectors.toList());
            }
        }

        return new Resources<>(users,
                linkTo(methodOn(UserController.class).retrieveAllUsers()).withSelfRel(),
                linkTo(methodOn(RootApiController.class).root()).withRel("root"));
    }

UserResourceAssembler:

@Component
public class UserResourceAssembler implements ResourceAssembler<User, Resource<User>> {
    @Override
    public Resource<User> toResource (User user) {
        return new Resource<>(user,
                linkTo(methodOn(UserController.class).retrieveUserById(user.getId())).withSelfRel(),
                linkTo(methodOn(UserController.class).retrieveUserTrips(user.getId())).withRel("trips"),
                linkTo(methodOn(UserController.class).retrieveAllUsers()).withRel("users"));
    }
}

Test is not passing, and Null Pointer Exception is thrown on retrieveAllUsers's

                users = userRepository.findAll().stream()
                        .map(userResourceAssembler::toResource)
                        .collect(Collectors.toList());

line.

I don't know what's going on- shouldn't findAll just return list of two users? Or is it some kind of error in toResource function?

Aucun commentaire:

Enregistrer un commentaire