2022.02.03-개발일지

회사 업무중 jenkins에서 빌드시 test 커버리지를 채우지 못하면 실패하도록 프로젝트를 구성하려 했습니다. 그러나 보안 이슈로 jenkins 내부와 데이터베이스간의 통신이 불가능하여 bean 생성이 정상적으로 되지 않았습니다. 이에 테스트틀 전부 mock으로 변경하였으나, @Value를 사용하지 못하게 되었습니다. 문제를 해결하기 위해 해당 resource를 spring이 아닌 코드상에서 직접 호출하는 방법으로 결정했고 해당 내용을 정리합니다.

Resource

Resource란 이미지, 오디오, 텍스트등과 같이 프로그램 코드와는 분리된 방식으로 접근하는 데이터를 의미합니다. 즉, 코드로 표현되지 않고 해당 데이터를 메모리에 로드해야 하는 것을 의미합니다.

Spring에선 Resource를 ResourceLoader interface를 제공하여 기본적으로 아래와 같은 형태로 Resource 및 각각의 ResourceLoader 를 제공합니다.

  • URLResource
  • ClassPathResource
  • FileSystemResource
  • ServletContextResource
  • InputStreamResource
  • ByteArrayResource

DefaultResourceLoader

spring에서 제공하는 DefaultResourceLoader를 사용하면 손쉽게 properties를 Resource 객체로 읽어들일 수 있습니다.

/*
* user.name=hahava
*/
@Test
void loadPropertiesTest() throws IOException{
  ResourceLoader propertiesLoader = new DefaultResourceLoader();
  Resource resource = propertiesLoader.getResource("application.properties");
  InputStreamReader inputStreamReader = new InputStreamReader(resource.getInputStream());
  
  Properties properties = new Properties();
  properties.load(inputStreamReader);

  assertThat(properties.get("user.name")).isEqaulTo("hahava))
}

만약, yaml 형식이라면 spring boot에 내장된 라이브러인 snakeyaml을 이용합니다. properties와 다른 점은 yaml.load()의해 파싱된 값들이 Map<String, LinkedList<Object>> 의 형태로 된다는 점임니다. 따라서 재귀 함수를 이용해 값을 읽어들일 수 있습니다.

/*
* user:
*   name: hahava
*/
@Test
void loadPropertiesTest() throws IOException {
  ResourceLoader propertiesLoader = new DefaultResourceLoader();
  Resource resource = propertiesLoader.getResource("application.yml");

  Yaml yaml = new Yaml();
  Map<String, Object> yamlProperties = yaml.load(resource.getInputStream());

  assertThat(getYmlValue("user.name", yamlProperties)).isEqualTo("hahava");
}

private String getYmlValue(String key, Map<String, Object> properties) {
  List<String> keys = Arrays.asList(key.split("\\."));
  if (keys.size() > 1) {
      return getYmlValue(
              String.join(".", keys.subList(1, keys.size())),
              (Map<String, Object>) properties.get(keys.get(0))
      );
  }

  return (String) properties.get(key);
}

카테고리:

업데이트:

댓글남기기