wasup

Spring) Note - 개념, 관계, 테스트케이스 JUnit 본문

IT/Java

Spring) Note - 개념, 관계, 테스트케이스 JUnit

wasupup 2021. 7. 31. 02:39
반응형

개념

컨트롤러 : 웹MVC(모델-뷰-컨트롤러)의 컨트롤러, 서비스를 통해 작동함( 컨트롤러가 서비스를 의존)

서비스 : 핵심 비즈니스 로직 구현(비즈니스에 가까움)

리포지토리 : 데이터베이스에 접근, 도메인 객체를 DB에 저장하고 관리

도메인 : 데이터베이스에 저장, 관리되는 비즈니스 도메인 객체


빈 등록1(어노테이션)

@Component : 컴포넌트 어노테이션이 있으면 빈으로 자동 등록

@Controller, @Service, @Repository : 컨트롤러가 스프링 빈으로 자동 등록

단, 메인메서드가 위치한 패키지의 하위 패키지부터 등록.

*스프링 컨테이너에 빈을 등록할 때 특별한 경우가 아니라면 기본으로 싱글톤 패턴으로 등록한다.

@Service
public class MemberService {

    private final MemberRepository memberRepository;

    @Autowired
    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    public Long join(Member member){
        validateDuplicateMember(member);//중복 회원 검증
        //통과하면
        memberRepository.save(member);//가입
        return member.getId();
    }

    private void validateDuplicateMember(Member member) {
        memberRepository.findByName(member.getName())
                        .ifPresent(m ->{
                            throw new IllegalStateException("이미 존재하는 회원입니다.");
                        });
    }

}

빈 등록2(직접 등록)

빈 등록은 자바 코드로 직접 등록할 수 있다.

@Configuration
public class SpringConfig {
    @Bean
    public MemberService memberService(){
        return new MemberService(memberRepository());
    }

    @Bean
    public MemberRepository memberRepository(){
        return new MemoryMemberRepository();
    }
}

 

*보통은 빈 등록을 어노테이션으로 진행한다.


DI ( Dependencies Injection)

* 기존 코드를 전혀 손대지 않고, 설정만으로 구현 클래스를 변경할 수 있음.

필드 주입, setter 주입, 생성자 주입 3가지가 있다.

 

필드 주입

@Controller
public class MemberController {
    
    //필드 주입
    @Autowired private MemberService memberService;

}

setter 주입

@Controller
public class MemberController {

	private MemberService memberService;

	//setter 주입 : 단점이라면 public으로 노출됨.
	@Autowired
	public void setMemberService(MemberService memberService) {
		this.memberService = memberService;
	}

}

생성자 주입

@Controller
public class MemberController {
    private final MemberService memberService;
	
    //생성자 주입 : 가장 권장됨.
    @Autowired
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }
}

 

*의존관계가 처음 주입시 외에 변하는 경우는 거의 없으므로 생성자 주입이 권장됨.

 


관계

Service -> Repository <- MemoryRepository


테스트케이스

작성한 소스가 제대로 동작하는지 검증.

main메서드를 실행하면 서버를 재시작해야하므로 시간이 오래걸리고 반복하기 어렵다.

특히 여러 테스트를 동시에 실행하기 어렵다.

JUnit이라는 프레임워크로 테스트를 실행할 수 있다.


테스트 어노테이션

@Test : 테스트 어노테이션이 선언된 메서드는 테스트 메서드가 됨.

@Before : @Test메서드가 실행되지 전에 반드시 실행

(*테스트 메서드에서 공통으로 사용하는 코드를 @Before메서드에 선언)

@AfterEach : @Test메서드가 실행된 후 실행

 

테스트 어노테이션 참고 링크 : https://shlee0882.tistory.com/202


JUnit 예제 )

org.junit.jupiter.api.Assertions

package com.was.repository;

import com.was.domain.Member;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

class MemoryMemberRepositoryTest {
    MemberRepository repository = new MemoryMemberRepository();

    @Test
    public void save(){
        Member member = new Member();
        member.setName("spring");

        repository.save(member);
        Member result = repository.findById(member.getId()).get();
        //System.out.println("(result == member = " + (result == member);
        //글자로 출력하는 대신 Assertions.assertEquals사용
        Assertions.assertEquals(member, result);
        
    }
}

package com.was.repository;

import com.was.domain.Member;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

class MemoryMemberRepositoryTest {
    MemberRepository repository = new MemoryMemberRepository();

    @Test
    public void save(){
        Member member = new Member();
        member.setName("spring");

        repository.save(member);
        Member result = repository.findById(member.getId()).get();
        
        Assertions.assertEquals(member, null);
        //결과
        //expected: <com.was.domain.Member@7654d46a> but was: <null>
        //기대한 값 : Expected :com.was.domain.Member@7654d46a
        //테스트 결과 값 : Actual   :null
    }
}

org.junit.jupiter.api.Assertions보다 편리한 org.assertj.core.api.Assertions

package com.was.repository;

import com.was.domain.Member;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

class MemoryMemberRepositoryTest {
    MemberRepository repository = new MemoryMemberRepository();

    @Test
    public void save(){
        Member member = new Member();
        member.setName("spring");

        repository.save(member);
        Member result = repository.findById(member.getId()).get();

        Assertions.assertThat(member).isEqualTo(result);
    }
}

static으로 사용하면 더 간단히 작성 가능.

package com.was.repository;

import com.was.domain.Member;
//import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.*;

class MemoryMemberRepositoryTest {
    MemberRepository repository = new MemoryMemberRepository();

    @Test
    public void save(){
        Member member = new Member();
        member.setName("spring");

        repository.save(member);
        Member result = repository.findById(member.getId()).get();

        assertThat(member).isEqualTo(result);
    }
}

 

반응형

'IT > Java' 카테고리의 다른 글

JUnit) 단위테스트와 통합테스트  (0) 2021.08.07
Spring Legacy MiNi Project - STS / member java  (0) 2021.08.05
Spring) 인텔리제이(IntelliJ)로 스프링 시작해보기  (0) 2021.07.28
JUnit) unit test!!!  (0) 2021.07.08
COMMENT 구조  (0) 2021.06.29
Comments