복붙노트

[SPRING] 동일한 인터페이스의 여러 모의 주입 방법

SPRING

동일한 인터페이스의 여러 모의 주입 방법

테스트하고자하는 Java 클래스 (ServiceCaller)는 다음과 같습니다.

@Autowired @Qualifier(value="serviceA")
SomeService serviceA;

@Autowired @Qualifier(value="serviceB")
SomeService serviceB;

(조건을 검사하고 A 또는 B 중 하나를 호출하는 doWork () 메소드가 있습니다).

어떻게 각 서비스 모의를 적절한 변수에 주입합니까?

내 Junit이 있습니다 :

@InjectMocks ServiceCaller classUnderTest = new ServiceCaller();

@Mock SomeService mockServiceA;
@Mock SomeService mockServiceB;

그러나 서비스 A / B가 올바른 조건에서 호출되었는지 확인하기 위해 테스트를 실행할 때 모의이 주입되지 않았으므로 null 포인터를 얻습니다.

분명히 같은 인터페이스 (SomeService)에 여러 의존성 때문에. 모의 서비스를 선언 할 때 한정자를 지정하는 방법이 있습니까? 또는 종속성에 대한 설정자를 필요로하고 구식 방식을 설정해야합니까?

해결법

  1. ==============================

    1.그것은 귀하의 모의 서비스 및 서비스의 이름을 지정하는 것으로 충분합니다. Mockito 문서에서 :

    그것은 귀하의 모의 서비스 및 서비스의 이름을 지정하는 것으로 충분합니다. Mockito 문서에서 :

    귀하의 예 :

    @InjectMocks ServiceCaller classUnderTest;
    
    @Mock SomeService serviceA;
    @Mock SomeService serviceB;
    

    @InjectMocks를 사용할 때 클래스 인스턴스를 수동으로 만들 필요는 없습니다.

    그럼에도 불구하고 나는 개인적으로 생성자를 사용하여 의존성을 주입하는 것을 선호한다. 그것은 테스트에서 모의 ​​(mock)를 삽입하는 것을 더 쉽게 만든다. (리플렉션 툴이나 @InjectMocks (유용하지만, 일부 aspect를 숨긴다)없이) 당신의 mock으로 생성자를 호출한다. 또한 TDD를 사용하면 테스트 된 클래스에 어떤 종속성이 필요한지 명확히 알 수 있으며 IDE에서도 생성자 스텁을 생성 할 수 있습니다.

    Spring Framework는 생성자 삽입을 완벽하게 지원합니다.

    @Bean
    public class ServiceCaller {
        private final SomeService serviceA;
        private final SomeService serviceB;
    
        @Autowired
        public ServiceCaller(@Qualifier("serviceA") SomeService serviceA,
                             @Qualifier("serviceB") SomeService serviceB) { ... }
    
        ...
    }
    

    이 코드는 다음을 사용하여 테스트 할 수 있습니다.

    @Mock SomeService serviceA;
    @Mock SomeService serviceB;
    
    //in a setup or test method
    ServiceCaller classUnderTest = new ServiceCaller(serviceA, serviceB); 
    
  2. ==============================

    2."name"속성을 사용하여 다음과 같이 인스턴스를 정의 할 수 있습니다.

    "name"속성을 사용하여 다음과 같이 인스턴스를 정의 할 수 있습니다.

    @Mock(name="serviceA") SomeService serviceA;
    @Mock(name="serviceB") SomeService serviceB;
    
  3. from https://stackoverflow.com/questions/21054057/how-to-inject-multiple-mocks-of-the-same-interface by cc-by-sa and MIT license