>source

내 서비스 구현 클래스 내에서 @Value를 사용하여 application.properties에서 값을 가져 오려고합니다. 잘 작동합니다. 그러나 테스트 케이스를 작성하는 동안 null이 발생합니다.

내부 서비스 impl 클래스

@Value("${transaction.service.process.layer.url}")
private String processLayerUrl;

테스트 파일

@RunWith(SpringRunner.class)
@WebMvcTest(value = TransactionServiceImpl.class)
@ActiveProfiles(profiles = "test")
@ContextConfiguration
//@ContextConfiguration(classes = TransactionServiceExperienceApplication.class)
//@SpringBootConfiguration(classes = { TransactionServiceExperienceApplicationTests.class })
//@TestPropertySource(locations="classpath:application-test.properties")
//@SpringBootTest(properties = { "transaction.service.process.layer.url =http://localhost:8087/v1/transaction-process-service" })
//@TestPropertySource(properties = { "transaction.service.process.layer.url = http://localhost:8087/v1/transaction-process-service" })
public class TransactionServiceImplTest {
    @Mock 
    private RestTemplate mockRestTemplate;
    
    @InjectMocks
    private TransactionServiceImpl transactionService;
    
    @Before
    public void setUp() {
        //transactionService = new TransactionServiceImpl("test");
        //ReflectionTestUtils.setField(transactionService, "processLayerUrl", "foo");
    }
    
    @Test 
    public void getTransactionDataListByAccountTest() throws Exception{
        
        Transaction transaction = new Transaction();
        transaction.setPosAccountNumber("40010020070401");
        
        HttpHeaders header = new HttpHeaders();
        header.setContentType(MediaType.APPLICATION_JSON);
        
        ArrayList<Object> mockResponseObj = new ArrayList<Object>();
        //Added data inside this object
        ResponseEntity<Object> responseEntity = new ResponseEntity<>(mockResponseObj, header, HttpStatus.OK);
        
        when(mockRestTemplate.postForEntity(
                ArgumentMatchers.anyString(), 
                ArgumentMatchers.eq(Transaction.class), 
                ArgumentMatchers.eq(Object.class))).thenReturn(responseEntity);
        
        ResponseEntity<Object> actualResponse = transactionService.getTransactionDataListByAccount(transaction);
        
        System.out.println("--- Response ---");
        System.out.println(actualResponse);
    }
    
    /*
     * @Configuration
     * 
     * @ComponentScan("transaction.service.experience.service") static class
     * someConfig {
     * 
     * // because @PropertySource doesnt work in annotation only land
     * 
     * @Bean PropertySourcesPlaceholderConfigurer propConfig() {
     * PropertySourcesPlaceholderConfigurer ppc = new
     * PropertySourcesPlaceholderConfigurer(); ppc.setLocation(new
     * ClassPathResource("application.properties")); return ppc; } }
     */
}

src/test/resources 안에 application-test.properties 파일을 지정했습니다.

여기 내 build.gradle이 있습니다.

testImplementation('org.springframework.boot:spring-boot-starter-test') {
    exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
implementation 'junit:junit:4.12'

이 restTemplate으로 인해 mock obj를 반환하는 대신 NullPointerException이 발생합니다.


  • 답변 # 1

    Spring Boot에서 제공하는 주석 대신 Mockito 주석을 사용하기 때문에 발생합니다.

    transactionService 주석을 달아야합니다. @AutowiredmockRestTemplate@MockBean .

    @MockBean Spring 애플리케이션 컨텍스트에서 원본 빈을 모의로 추가하거나 대체하고 종속성으로 필요한이 컨텍스트의 빈에 삽입합니다.

    작성중인 테스트가 통합 테스트 인 경우 transactionService를 수동으로 인스턴스화해서는 안됩니다.

    여기서 무엇을 테스트하고 있는지 재고해야합니다. WebMvc 테스트는 서비스가 아닌 컨트롤러를 테스트하기위한 것입니다. 서비스를 테스트하고 싶다면-Spring없이 일반 단위 테스트를 작성하는 것을 고려하십시오. 실제 통합 테스트를 원한다면 @SpringBootTest .

관련 자료

  • 이전 python - 인쇄 대신 재귀 함수의 결과를 저장하는 방법
  • 다음 dart - 일반 메서드를 재정의하는 방법은 무엇입니까?