Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSON 출력기 만들기 #98

Merged
merged 4 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
public enum ExportFileType {
CSV,
TSV,
// JSON, // TODO: 강의 시간 상 구현을 생략함. 구현하면 TODO 삭제
JSON,
// SQL_INSERT, // TODO: 강의 시간 상 구현을 생략함. 구현하면 TODO 삭제
;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package uno.fastcampus.testdata.service.exporter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import uno.fastcampus.testdata.domain.constant.ExportFileType;
import uno.fastcampus.testdata.dto.SchemaFieldDto;
import uno.fastcampus.testdata.dto.TableSchemaDto;
import uno.fastcampus.testdata.service.generator.MockDataGeneratorContext;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Slf4j
@RequiredArgsConstructor
@Component
public class JsonFileExporter implements MockDataFileExporter {

private final MockDataGeneratorContext mockDataGeneratorContext;
private final ObjectMapper mapper;

@Override
public ExportFileType getType() {
return ExportFileType.JSON;
}

@Override
public String export(TableSchemaDto dto, Integer rowCount) {
try {
List<Map<String, Object>> list = new ArrayList<>();

IntStream.range(0, rowCount).forEach(i -> {
Map<String, Object> map = new LinkedHashMap<>();
dto.schemaFields().stream()
.sorted(Comparator.comparing(SchemaFieldDto::fieldOrder))
.forEach(field -> {
map.put(field.fieldName(), mockDataGeneratorContext.generate(
djkeh marked this conversation as resolved.
Show resolved Hide resolved
field.mockDataType(),
field.blankPercent(),
field.typeOptionJson(),
field.forceValue()
));
});
list.add(map);
});

return mapper.writeValueAsString(list);
} catch (JsonProcessingException e) {
log.warn("테이블 스키마 데이터를 JSON으로 변환하는데 실패했습니다 - {}", dto, e);
return "";
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package uno.fastcampus.testdata.service.exporter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
import uno.fastcampus.testdata.domain.constant.ExportFileType;
import uno.fastcampus.testdata.domain.constant.MockDataType;
import uno.fastcampus.testdata.dto.SchemaFieldDto;
import uno.fastcampus.testdata.dto.TableSchemaDto;
import uno.fastcampus.testdata.service.generator.MockDataGeneratorContext;

import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.*;
import static org.mockito.Mockito.times;

@DisplayName("[Logic] Json 파일 출력기 테스트")
@ExtendWith(MockitoExtension.class)
class JsonFileExporterTest {

@InjectMocks private JsonFileExporter sut;

@Mock private MockDataGeneratorContext mockDataGeneratorContext;
@Spy private ObjectMapper mapper;

@DisplayName("이 파일 출력기의 유형은 JSON이다.")
@Test
void givenNothing_whenCheckingType_thenReturnsJsonType() {
// Given

// When & Then
assertThat(sut.getType()).isEqualTo(ExportFileType.JSON);
}

@DisplayName("테이블 스키마 정보와 행 수가 주어지면, JSON 형식의 문자열을 생성한다.")
@Test
void givenSchemaAndRowCount_whenExporting_thenReturnsJsonFormattedString() throws Exception {
// Given
TableSchemaDto dto = TableSchemaDto.of(
"test_schema",
"uno",
null,
Set.of(
SchemaFieldDto.of("id", MockDataType.ROW_NUMBER, 1, 0, null, null),
SchemaFieldDto.of("name", MockDataType.NAME, 2, 0, null, null),
SchemaFieldDto.of("created_at", MockDataType.DATETIME, 5, 0, null, null),
SchemaFieldDto.of("age", MockDataType.NUMBER, 3, 0, null, null),
SchemaFieldDto.of("car", MockDataType.CAR, 4, 0, null, null)
)
);
int rowCount = 10;
given(mockDataGeneratorContext.generate(any(), any(), any(), any())).willReturn("test-value");

// When
String result = sut.export(dto, rowCount);

// Then
System.out.println(result); // 관찰용
djkeh marked this conversation as resolved.
Show resolved Hide resolved
assertThat(result)
.startsWith("[")
.endsWith("]")
.contains("""
{"id":"test-value","name":"test-value","age":"test-value","car":"test-value","created_at":"test-value"}"""
);
then(mockDataGeneratorContext).should(times(rowCount * dto.schemaFields().size())).generate(any(), any(), any(), any());
then(mapper).should().writeValueAsString(any());
}

@DisplayName("JSON 변환에 실패하면, 빈 문자열을 반환한다.")
@Test
void givenSchemaAndRowCount_whenFailingToJsonFormatting_thenReturnsEmptyString() throws Exception {
// Given
TableSchemaDto dto = TableSchemaDto.of("test_schema", "uno", null, Set.of(SchemaFieldDto.of("id", MockDataType.ROW_NUMBER, 1, 0, null, null)));
int rowCount = 10;
given(mockDataGeneratorContext.generate(any(), any(), any(), any())).willReturn("test-value");
willThrow(JsonProcessingException.class).given(mapper).writeValueAsString(any());

// When
String result = sut.export(dto, rowCount);

// Then
assertThat(result).isEqualTo("");
then(mockDataGeneratorContext).should(times(rowCount * dto.schemaFields().size())).generate(any(), any(), any(), any());
then(mapper).should().writeValueAsString(any());
}

}
Loading