본문 바로가기
스프링

DI는 생성자 주입으로 하자

by 리포터12 2023. 3. 30.
728x90
class OrderServiceImplTest {

   @Test
   void createOrder() {
      OrderServiceImpl orderService = new OrderServiceImpl();
      orderService.createOrder(1L, "itemA", 10000);

   }
}

해당 테스트의 결과는 

java.lang.NullPointerException 이다.

@Override
public Order createOrder(long memberId, String itemName, int itemPrice) {
   Member member = memberRepository.findById(memberId);
   int discountPrice = discountPolicy.discount(member, itemPrice);

   return new Order(memberId, itemName, itemPrice, discountPrice);
}

createOrder() 를 수행하려면 memberRepository 랄 discountPolicy가 필요한데,

private MemberRepository memberRepository ;
private DiscountPolicy discountPolicy;

public void setMemberRepository(MemberRepository memberRepository) {
   this.memberRepository = memberRepository;
}

public void setDiscountPolicy(DiscountPolicy discountPolicy) {
   this.discountPolicy = discountPolicy;
}

해당 필드들을 setter 로 주입하고 있거덩.

 

독립된 테스트 클래스에서 필요한 객체 주입을 받지 않았으니 당연히 null이 뜬다. 

 

흠흠.

그럼 테스트에서 Service 객체를 생성해서 바로 Service의 메서드를 실행하기 위해선 어떻게 해야할까?

-> 지금 테스트가 안 되는 이유는?

-> 의존 주입이 안 돼 있어서

-> 의존주입이 안 된 이유는?

-> 의존주입하는 코드가 실행이 안 되서

=> 그럼 객체 생성할 때 의존 주입 받으면 되겠다.

 

private final MemberRepository memberRepository ;
private final DiscountPolicy discountPolicy;

// public void setMemberRepository(MemberRepository memberRepository) {
//     this.memberRepository = memberRepository;
// }
//
// public void setDiscountPolicy(DiscountPolicy discountPolicy) {
//     this.discountPolicy = discountPolicy;
// }

@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
   this.memberRepository = memberRepository;
   this.discountPolicy = discountPolicy;
}

 

기왕 바꾼거 필드들도 final 로 바꿔주었다.

 

테스트 코드도 조금 조물딱 거려주고,

@Test
void createOrder() {
   MemoryMemberRepository memberRepository = new MemoryMemberRepository();
   memberRepository.save(new Member(1L, "strongB,", Grade.VIP));
   OrderServiceImpl orderService = new OrderServiceImpl(memberRepository, new FixDiscountPolicy());

   Order order = orderService.createOrder(1L, "itemA", 10000);
   assertThat(order.getDiscountPrice()).isEqualTo(1000);
}

아, 잘 돌아간다.. 편안

 

Mock 라이브러리를 이용하여 가짜 객체를 생성하여 테스트 하는 방법도 있는 모양이다.

 

 

참조 자료

스프링 핵심 원리 - 기본편 (김영한)

728x90

댓글