시배's Android

Hi Jack Mocker | 개선기 (2) feat.JSON 변환 이슈 본문

Android/Hi Jack Mocker

Hi Jack Mocker | 개선기 (2) feat.JSON 변환 이슈

si8ae 2024. 7. 12. 18:09

Hi Jack Mocker란?

 

GitHub - koreatlwls/Hi-Jack-Mocker: Hi-Jack-Mocker is a project that leverages OkHttp3's interceptor to intercept and modify net

Hi-Jack-Mocker is a project that leverages OkHttp3's interceptor to intercept and modify network requests and responses, allowing you to verify the UI easily. - koreatlwls/Hi-Jack-Mocker

github.com

 

Hi Jack Mocker는 비개발자도 UI 엣지 케이스를 쉽게 테스트할 수 있도록 돕는 라이브러리입니다. 이 프로젝트는 OkHttp3 인터셉터를 활용하여 네트워크 요청과 응답을 가로채고 수정할 수 있게 합니다. 이를 통해 개발자뿐만 아니라 다양한 사용자들이 다양한 시나리오를 테스트할 수 있게 합니다.

 

SingleItem 클래스의 value 타입을 Any로 변경하여 JSON 변환 문제 해결하기

HiJackMocker 라이브러리의 SingleItem 클래스에서 value의 타입을 String에서 Any로 변경한 이유와 그로 인해 해결한 문제들에 대해 다루겠습니다.

기존의 SingleItem 클래스와 문제점

기존의 SingleItem 클래스는 다음과 같이 value를 String 타입으로 한정하고 있었습니다:

data class SingleItem(
    override val key: String,
    val value: String
) : JsonItem

SingleItem 클래스는 JSON 데이터를 String 값으로만 표현할 수 있어서, 다양한 JSON 데이터 타입을 처리하는 데 한계가 있었습니다. 실제 JSON 객체에서는 String 외에도 Int, Double, Boolean 등 다양한 데이터 타입이 존재할 수 있습니다.

이로 인해 SingleItem을 사용하여 UI에 JSON 데이터를 표시하고, MockingJSON 객체로 다시 변환하는 과정에서 여러 문제가 발생했습니다. 예를 들어, Int, Double, Boolean과 같은 기본형 타입이 String으로만 처리되다 보니, Mocking이 완료된 이후 JSON 객체로 변환할 때 문제가 발생했습니다.

이런 문제로 인해 MoshiGson과 같은 JSON 변환 라이브러리에서 에러가 발생할 수 있었습니다.

SingleItem 클래스의 개선

문제를 해결하기 위해 SingleItem 클래스의 value 타입을 Any로 변경했습니다.

data class SingleItem(
    override val key: String,
    val value: Any
) : JsonItem

Any 타입으로 변경함으로써 String뿐만 아니라 Boolean, Int, Float, Double 등 다양한 JSON 데이터 타입을 지원할 수 있게 되었습니다.

이제 SingleItem은 JSON의 모든 기본형 타입을 처리할 수 있으며, Mocking 완료 후에도 JSON 객체를 정확하게 재생성할 수 있습니다.

UI에서 SingleItem의 value를 표시하는 방법

value의 타입이 Any가 되면서, UI를 그릴 때 value의 실제 타입에 따라 다른 방법으로 표시하도록 개선했습니다. 예를 들어, Boolean, Int, Float, Double 등의 타입에 따라 UI를 다르게 표현합니다.

is JsonItem.SingleItem -> {
            when (item.value) {
                is Boolean -> {
                    BooleanValue(
                        value = item.value,
                        onValueChange = { onValueChange(it) }
                    )
                }

                is Int, is Long, is Float, is Double -> {
                    NumberValue(
                        value = item.value,
                        onValueChange = { onValueChange(it) }
                    )
                }

                else -> {
                    TextValue(
                        value = item.value.toString(),
                        onValueChange = { onValueChange(it) }
                    )
                }
            }
        }

여기서 BooleanValue, NumberValue, TextValue는 각 타입에 맞는 UI 컴포넌트를 보여줍니다.

@NonNull public JSONObject put(@NonNull String name, @Nullable Object value) throws JSONException {
        if (value == null) {
            nameValuePairs.remove(name);
            return this;
        }
        if (value instanceof Number) {
            // deviate from the original by checking all Numbers, not just floats & doubles
            JSON.checkDouble(((Number) value).doubleValue());
        }
        nameValuePairs.put(checkName(name), value);
        return this;
    }

JSONObject의 put 함수는 Object 타입의 값을 허용하기 때문에, SingleItem 클래스의 value를 String에서 Any로 변경하면 JSON 변환 과정에서 발생할 수 있는 문제를 해결할 수 있었습니다.