@Service
@Slf4j
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
private final FileService fileService;
private final FileDBService fileDBService;
private final EncryptAlgorithm encryptAlgorithm;
@Override
public Optional<Member> login(String id, String password) throws EncryptAlgorithmFailException {
return memberRepository.findMemberByPasswordAndId(id, encryptAlgorithm.encrypt(password));
}
@Override
@Transactional
public Member register(MemberRegisterForm memberRegisterForm, MultipartFile profileFile) throws IOException {
Member member = createMember(memberRegisterForm);
if(FileUtil.doesFileExist(profileFile)){
UploadFile uploadFile = fileService.storeFile(profileFile, member);
member.setUploadFile(uploadFile);
}
return memberRepository.save(member);
}
}
...
로그인과 회원 등록에 관한 테스트 코드 작성
@ExtendWith(MockitoExtension.class) //mock 객체 사
class MemberServiceImplTest {
@InjectMocks
private MemberServiceImpl memberService;
@Mock
private MemberRepository memberRepository;
private static MockedStatic<FileUtil> fileUtil;
@Spy
private SHA256 encryptAlgorithm;
@BeforeAll
public static void beforeAll(){
fileUtil = mockStatic(FileUtil.class);
}
@AfterAll
public static void afterAll(){
fileUtil.close();
}
@Test
public void 회원가입_성공_프로필사진_없음() throws Exception{
//given
String id = "choi1234";
String password = "1234";
String nickname = "maxx";
MemberRegisterForm memberRegisterForm = new MemberRegisterForm();
memberRegisterForm.setId(id);
memberRegisterForm.setNickname(nickname);
memberRegisterForm.setPassword(password);
doReturn(new Member("M123456789", id, nickname, encryptAlgorithm.encrypt("1234"))).when(memberRepository).save(any(Member.class));
when(FileUtil.doesFileExist(any(MultipartFile.class))).thenReturn(false);
//when
Member registeredMember = memberService.register(memberRegisterForm, any(MultipartFile.class));
//then
assertThat(memberRegisterForm.getId()).isEqualTo(registeredMember.getId());
assertThat(memberRegisterForm.getNickname()).isEqualTo(registeredMember.getNickname());
assertThat(encryptAlgorithm.encrypt(memberRegisterForm.getPassword())).isEqualTo(registeredMember.getPassword());
}
@Test
public void 회원가입_성공_프로필사진_있음() throws Exception{
//given
String id = "choi1234";
String password = "1234";
String nickname = "maxx";
MemberRegisterForm memberRegisterForm = new MemberRegisterForm();
memberRegisterForm.setId(id);
memberRegisterForm.setNickname(nickname);
memberRegisterForm.setPassword(password);
//MultipartFile mock
MultipartFile multipartFile = new MockMultipartFile("file"
, "test.png"
, "img/png"
, new FileInputStream("/Users/choidayoung/dev/file/before/test.png"));
UploadFile uploadFile = new UploadFile(123456789L, id, "eedx-3343-48c83-3jdj.png", "/Users/choidayoung/dev/file/profile/dev", "test.png");
// doReturn(uploadFile).when(fileService).storeFile(any(MultipartFile.class), any(Member.class));
Member member = new Member("M123456789", id, nickname, encryptAlgorithm.encrypt(password));
member.setUploadFile(uploadFile);
doReturn(member).when(memberRepository).save(any(Member.class));
//when
Member registeredMember = memberService.register(memberRegisterForm, multipartFile);
//then
assertThat(memberRegisterForm.getId()).isEqualTo(registeredMember.getId());
assertThat(memberRegisterForm.getNickname()).isEqualTo(registeredMember.getNickname());
assertThat(encryptAlgorithm.encrypt(memberRegisterForm.getPassword())).isEqualTo(registeredMember.getPassword());
assertThat(registeredMember.getUploadFile().getId()).isNotNull();
assertThat(registeredMember.getUploadFile().getLocalFileName()).isNotEmpty();
}
@Test
public void 로그인_성공() throws Exception{
//given
String id = "choi1234";
String password = "1234";
String encryptPassword = encryptAlgorithm.encrypt(password);
Member member = new Member("M123456789", encryptPassword, "maxx", id);
doReturn(Optional.of(member)).when(memberRepository).findMemberByPasswordAndId(id, encryptPassword);
//when
Optional<Member> loginMember = memberService.login(id, password);
//then
assertThat(loginMember.get().getMemberId()).isEqualTo(member.getMemberId());
assertThat(loginMember.get().getNickname()).isEqualTo(member.getNickname());
}
}
테스트를 하는 데 가장 메인이 되는 클래스인 MemberService는 @InjectMocks 해주고, 나머지 클래스들은 @Mock 처리. 비밀번호 암호화 클래스는 진짜 사용해야하므로 @Spy 처리 해줌.
static method의 경우 stub하려면 3.0.0 이상의'org.mockito:mockito-inline' 라이브러리가 필요했음
private static MockedStatic<FileUtil> fileUtil;
@BeforeAll
public static void beforeAll(){
fileUtil = mockStatic(FileUtil.class);
}
@AfterAll
public static void afterAll(){
fileUtil.close();
}
when(FileUtil.doesFileExist(any(MultipartFile.class))).thenReturn(false);
이렇게 구성하면 stub을 할 수 있음
chaining method mock 객체 삽입하려면
A.getB().getId();
순서 중요!
when(B.getId()).thenReturn(123456L);
when(A.getB()).thenReturn(B);
이렇게 오른쪽에서 왼쪽으로 객체를 stub해주어야 함