Как проверить объект JSON как неупорядоченный список?

#go

#Вперед

Вопрос:

У меня есть конечная точка, написанная на Go. Когда вы вызываете его с запросом GET, он возвращает следующие данные об успешном выполнении (200):

 {"Q":[{"A":"D","M":{"F":{"J":4,"K":3,"L":1}},"R":"S"},{"A":"E","M":{"F":{"J":4,"K":3,"L":1}},"R":"T"}]}
  

Теперь я пытаюсь написать тестовый пример, который проверит возвращаемые данные из этой конечной точки и убедится, что это так, как указано выше. Но порядок двух объектов внутри списка не имеет значения. Т.Е. Если второй элемент идет первым, тестовый пример все равно должен пройти.

Как мне это сделать?

Пока я использую mapset s отсюда для реализации неупорядоченных списков в тестовом примере, подобном этому:

  1  statusCode, bodyBytes, err := myHTTPRequestFunc(http.MethodGet, uri, headers, bytes.NewBuffer(body))
 2  assert.Nil(t, err)
 3  unmarshalledBody := make(map[string]interface{})
 4  err = json.Unmarshal(bodyBytes, amp;unmarshalledBody)
 5  assert.Nil(t, err)
 6  assert.Equal(t, http.StatusOK, statusCode)
 7  myList := unmarshalledBody["Q"].([]interface{})
 8  assert.Equal(t, 2, len(myList))
 9
10  expectedContexts := mapset.NewSet(). // mapset comes from here https://github.com/deckarep/golang-set
11  var jsonMap map[string](interface{})
12  var b []byte
13
14  jsonMap = make(map[string](interface{}))
15  b = []byte(`{"A":"D","M":{"F":{"J":4,"K":3,"L":1}},"R":"S"}`)
16  assert.Nil(t, json.Unmarshal([]byte(b), amp;jsonMap))
17  expectedContexts.Add(jsonMap)
18
19  jsonMap = make(map[string](interface{}))
20  b = []byte(`{"A":"E","M":{"F":{"J":4,"K":3,"L":1}},"R":"T"}`)
21  assert.Nil(t, json.Unmarshal([]byte(b), amp;jsonMap))
22  expectedContexts.Add(jsonMap)
23
24  receivedContexts := mapset.NewSet() // mapset comes from here https://github.com/deckarep/golang-set
25  receivedContexts.Add(myList[0])
26  receivedContexts.Add(myList[1])
27
28  assert.Equal(t, expectedContexts, receivedContexts)
  

Но когда я запускаю этот тестовый пример, я получаю следующую ошибку в строке # 17 при попытке добавить элемент в набор карт:

 panic: runtime error: hash of unhashable type map[string]interface {}
  

Как я могу правильно добавить эти элементы в mapset ?
Есть ли лучший / более простой / другой подход для выполнения этой проверки?

Комментарии:

1. Похоже mapset , использует значения, которые вы добавляете к нему, в качестве ключа карты. Карты, sllices не могут использоваться в качестве ключей карты. Если все, что вам нужно, это сравнить две карты, вы можете использовать reflect.DeepEqual

Ответ №1:

Вы можете использовать reflect.DeepEqual функцию для сравнения неупорядоченного интерфейса тела с ожидаемым результатом по вашему выбору

Предполагая unmarshalledBody , что у вас уже есть доступный, сформируйте интерфейс на основе ожидаемого результата, чтобы сравнить его с

 expected := `{"Q":[{"A":"D","M":{"F":{"J":4,"K":3,"L":1}},"R":"S"},{"A":"E","M":{"F":{"J":4,"K":3,"L":1}},"R":"T"}]}`
expectedBody := make(map[string]interface{})
if err := json.Unmarshal([]byte(expected), amp;expectedBody); err != nil {
    return
}   

result := reflect.DeepEqual(unmarshalledBody, expectedBody)
  

Функция сравнения возвращает логическое значение в зависимости от результата сопоставления. Вы можете подтвердить это, если оно возвращает true .

Демонстрация Go playground