Why Do I need default value in WithMockCustomUser?

Viewed 21

I made a test Using @WithMockCustomUser annotation. Since My Service Logic needs User's email, I needed to make CustomSecurirtyContextFactory. So I made it and Use it in WithMockCustomUser

What I'm wondering is that why should I need default value in WithMockCustomUser?

I've already set values in CustomUserDetails in WithMockCustomUserSecurityContextFactory.. I've checked values and find out that default values are not used.. Test is using values in CustomUserDetails so those default values looks meaningless to me.

Let me show you my code

Service I'm trying to test

public class CommentService {

    private final CommentRepository commentRepository;
    private final PostsRepository postsRepository;
    private final UserDetailService userDetailService;

    @Transactional
    public Long commentSave(CommentSaveRequestDto requestDto, Long id) {
        Posts post = postsRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("해당 게시글이 존재하지 않습니다"));
        requestDto.setPosts(post);

        User user = userDetailService.returnUser();
        requestDto.setUser(user);

        return commentRepository.save(requestDto.toEntity()).getId();
    }

UserDetailService used In above service

@RequiredArgsConstructor
@Service
public class UserDetailService implements UserDetailsService {

    private final UserRepository userRepository;

    public User returnUser() {
        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        String userName;

        if (principal instanceof UserDetails) {
            userName = ((UserDetails) principal).getUsername();
        } else {
            userName = principal.toString();
        }

        System.out.println("유저 : " + userName);

        int start = userName.indexOf("email")+6;
        int end = userName.indexOf(".com,")+4;
        String email = userName.substring(start, end);

        System.out.println("이메일 : " + email);

        User user = userRepository.findByEmail(email).orElse(null);

        return user;
    }

    public Principal returnPrincipal() {
        return (Principal) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    }
}

WithMockCustomUser

@Retention(RetentionPolicy.RUNTIME)
@WithSecurityContext(factory = WithMockCustomUserSecurityContextFactory.class, setupBefore = TestExecutionEvent.TEST_EXECUTION)
public @interface WithMockCustomUser {
    String name() default "testName";

    String email() default "testEmail@naver.com";

    Role role() default Role.USER;
}

WithMockCustomUserSecurityContextFactory used with WithMockCustomUser

class WithMockCustomUserSecurityContextFactory implements WithSecurityContextFactory<CommentsApiControllerTest.WithMockCustomUser> {
    @Override
    public SecurityContext createSecurityContext(CommentsApiControllerTest.WithMockCustomUser customUser) {
        SecurityContext context = SecurityContextHolder.createEmptyContext();

        CustomUserDetails principal = new CustomUserDetails();
        Authentication auth =
                new UsernamePasswordAuthenticationToken(principal, "password", principal.getAuthorities());
        context.setAuthentication(auth);
        return context;
    }
}

CustomUserDetails used in WithMockCustomUserSecurityContextFactory above

@Getter
class CustomUserDetails implements UserDetails {

    public  String name = "ㅇㅇ";
    public String email = "1park5@naver.com";

    public String role  = Role.USER.toString();

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        ArrayList<GrantedAuthority> auth = new ArrayList<GrantedAuthority>();
        auth.add(new SimpleGrantedAuthority((role)));

        return auth;
    }

    @Override
    public String getPassword() {
        return null;
    }

    @Override
    public String getUsername() {
        return "email="+email+",";
    }

    @Override
    public boolean isAccountNonExpired() {
        return false;
    }

    @Override
    public boolean isAccountNonLocked() {
        return false;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return false;
    }

    @Override
    public boolean isEnabled() {
        return false;
    }
}

Test Code

@Test
    @WithMockCustomUser
    @Transactional // 프록시 객체에 실제 데이터를 불러올 수 있게 영속성 컨텍스트에서 관리
    public void comment_등록() throws Exception {
        // given
        String title = "title";
        String content = "content";
        User user = userRepository.save(User.builder()
                .name("name")
                .email("fake@naver.com")
                .picture("fakePic.com")
                .role(Role.USER)
                .build());

        PostsSaveRequestDto requestDto = PostsSaveRequestDto.builder()
                .title(title)
                .content(content)
                .user(user)
                .build();
        postsRepository.save(requestDto.toEntity());

        String comment = "comment";
        Posts posts = postsRepository.findAll().get(0);

        CommentSaveRequestDto saveRequestDto = CommentSaveRequestDto.builder()
                .comment(comment)
                .posts(posts)
                .build();

        Long id = posts.getId();

        String url = "http://localhost:"+ port + "/api/posts/" + id + "/comments";

        //when

        mvc.perform(post(url)
                        .contentType(MediaType.APPLICATION_JSON_UTF8)
                        .content(objectMapper.writeValueAsString(saveRequestDto)))
                .andDo(print())
                .andExpect(status().isOk());

    }

This doc helped me made this test

At least this test is successfully passed, I'm not Sure I made it correctly. Any comments would be very helpful. Thank you in advance.

0 Answers
Related