2017-11-30 1 views
1

종속성 주입에 SpringBoot를 사용하는 응용 프로그램이 있는데 응용 프로그램이 제대로 작동하지만 테스트 중에 @Autowired 필드가 주입되지 않기 때문에 테스트가 실패합니다.SpringBootTest와 함께 dependency-injection을 사용하는 방법

@SpringBootApplication 
public class ProcessorInterface { 
    protected final static Logger logger = Logger.getLogger(ProcessorInterface.class); 

    public static void main(String[] args) { 
     try { 
      SpringApplication.run(ProcessorInterfaceRunner.class, args); 
     } catch (Exception ex) { 
      logger.error("Error running ProcessorInterface", ex); 
     } 
    } 
} 


@Component 
@Configuration 
@ComponentScan 
public class ProcessorInterfaceRunner implements CommandLineRunner { 
    protected final static Logger logger = Logger.getLogger(ProcessorInterface.class); 

    @Autowired 
    private RequestService requestService = null; 
    @Autowired 
    private ValidatorService validatorService = null; 

    @Override 
    public void run(String... args) throws Exception { 

     ESPOutTransaction outTransaction = null; 
     outTransaction = new ESPOutTransaction(); 
     // initialize outTransaction fields 
     ... 
     // done initializing outTransaction fields 

     if (validatorService.isValid(outTransaction)) { 
      System.out.println(requestService.getRequest(outTransaction)); 
     } else { 
      System.out.println("Bad Data"); 
     } 
    } 
} 


@Service 
public class ESPRequestService implements RequestService<ESPOutTransaction> { 

    @Autowired 
    ValidatorService validatorService = null; 

    @Override 
    public String getRequest(ESPOutTransaction outTransaction) throws IllegalArgumentException { 
     if (!validatorService.isValid(outTransaction)) { 
      throw new IllegalArgumentException("Invalid parameters in transaction object. " + outTransaction.toString()); 
     } 

     StringBuffer buff = new StringBuffer("create request XML"); 
     buff.append("more XML"); 
     return buff.toString(); 
    } 
} 


@Service 
public class ESPValidatorService implements ValidatorService { 
    private static org.apache.log4j.Logger logger = Logger.getLogger(ESPValidatorService.class); 

    // declare some constants for rules 
    private static final int MAX_LENGTH_XYZ = 3; 

    @Override 
    public boolean isValid(OutTransaction outTransaction) { 
     ESPOutTransaction espOutTransaction = (ESPOutTransaction)outTransaction; 
     boolean isValid = true; 

     if (espOutTransaction == null) { 
      logger.warn("espOutTransaction is NULL"); 
      isValid = false; 
     } else { 
      // XYZ is required 
      if (espOutTransaction.getXYZ() == null) { 
       logger.warn("XYZis NULL\r\n" + espOutTransaction.toString()); 
       isValid = false; 
      } 
      // XYZ max length = MAX_LENGTH_XYZ 
      if (espOutTransaction.getXYZ() != null && espOutTransaction.getPubCode().trim().length() > MAX_LENGTH_XYZ) { 
       logger.warn("XYZis too long (max length " + MAX_LENGTH_XYZ + ")\r\n" + espOutTransaction.toString()); 
       isValid = false; 
      } 
     } 
     return isValid; 
    } 
} 

이 모든 것들이 작동하며 앱을 실행할 때 좋은 결과를 얻습니다. 그래도 난 그것을 테스트 할 때이 ESPValidatorService이

@RunWith(Suite.class) 
@SuiteClasses({ ESPOutTransactionValidatorTest.class, ESPRequestTest.class }) 
public class AllTests {} 


@RunWith(SpringRunner.class) 
@SpringBootTest(classes = {ESPRequestService.class}) 
public class ESPRequestTest { 

    @Test 
    public void testGetRequest() { 
     ESPRequestService requestService = new ESPRequestService(); 

     String XYZ = "XYZ"; 

     ESPOutTransaction outTransaction = null; 
     outTransaction = new ESPOutTransaction(); 
     outTransaction.setXYZ(XYZ); 

     String strRequest = "some expected request XML"; 
     String request = requestService.getRequest(outTransaction); 
     assertEquals(request, strRequest); 
    } 
} 


@RunWith(SpringRunner.class) 
@SpringBootTest(classes = ESPValidatorService.class) 
public class ESPOutTransactionValidatorTest { 

    @Test 
    public void testIsValid() { 
     ESPValidatorService validatorService = new ESPValidatorService(); 

     ESPOutTransaction outTransaction = null; 
     // test request = null 
     assertFalse(validatorService.isValid(outTransaction)); 

     String XYZ = "XYZ"; 

     outTransaction = new ESPOutTransaction(); 
     outTransaction.setXYZ(XYZ); 

     // test all good 
     assertTrue(validatorService.isValid(outTransaction)); 

     // test XYZ 
     outTransaction.setXYZ(null); 
     assertFalse(validatorService.isValid(outTransaction)); 
     outTransaction.setXYZ("ABCD"); // too long 
     assertFalse(validatorService.isValid(outTransaction)); 
     outTransaction.setXYZ(XYZ); 
    } 
} 

가 어떻게 자동 와이어에 대한 단위 테스트를 얻을 수 ESPRequestService

에 주입 찾을 수 없기 때문에, 그것은 실패?

답변

2

나는 두 가지 문제를 참조하십시오

1) 스프링 빈에 의존하지 않는를하지만 당신은 new 연산자 인스턴스를 만들 수 있습니다. 대신 글을 쓰는

:

ESPRequestService requestService = new ESPRequestService(); 

당신이 봄 인스턴스를 주입 할 수 있도록해야합니다

@Bean 
ESPRequestService requestService; 

2) @SpringBootTest 구성이 올바르지 않습니다.

@SpringBootTest(classes = ESPValidatorService.class) 
public class ESPOutTransactionValidatorTest { 

@SpringBootTest(classes = {ESPRequestService.class}) 
public class ESPRequestTest { 

그러나 @SpringBootTestclasses 속성을 사용하는 주석 클래스를 지정하는 역할을한다 : 각 테스트에서

, 당신은 @SpringBootTestclasses 속성에 매우 구체적인 빈 클래스를 지정 ApplicationContext를로드하기위한 메소드.

주석 클래스는 ApplicationContext를로드하는 데 사용할 수 있습니다. 도 @ContextConfiguration(classes=...)을 사용하여 지정할 수 있습니까? 명시 적 클래스가 정의되지 않은 경우 테스트에서는 SpringBootConfiguration 검색으로 되돌아 가기 전에 중첩 된 @Configuration 클래스를 찾습니다.

따라서 응용 프로그램의 모든 구성 클래스와 bean이 발견되어 Spring 컨테이너에로드되지 않을 수 있습니다.

하면 테스트, 가장 간단한 방법은 @SpringBootTest 주석의 classes 속성을 지정하지 않는 동안 모든 응용 프로그램 콩을로드 할 수 있으려면 :

@SpringBootTest 
public class ESPRequestTest { ...} 
그것은 @SpringBootConfiguration을 유지하는 스프링 빈을 찾을 것이다

.
이상적으로 애플리케이션의 @SpringBootApplication 빈을 발견 할 수 있습니다.
테스트 클래스의 패키지가 @SpringBootApplication 클래스의 패키지 (또는 하위 레벨) 내에있는 경우 자동으로 검색해야합니다.

그렇지 않으면 다른 방법은 필요한 모든 콩을로드 할 수 있도록 구성 지정되어

@SpringBootTest(classes = MySpringBootApplication.class) 
public class ESPRequestTest { ...} 
+0

이것은 내가 가진 유일한 문제는 아니었다, 그러나 그것은 나를 올바른 방향으로 지적되었다. –

관련 문제