lundi 10 décembre 2018

Golang: Create a function that test marshalling/unmarshalling from an interface

I want to create a simple function to test that marshalling/unmarshalling a record works as intended. I'm just using JSON for this example:

package test

import (
    "encoding/json"
    "fmt"
    "testing"
    "reflect"

    "github.com/stretchr/testify/require"
)

func CheckRoundTripJSON(t *testing.T, record interface{}) {
    data, err := json.Marshal(record)
    require.NoError(t, err)
    fmt.Println("Record: ", record, " was encoded to: ", data, " - Type: ", reflect.TypeOf(record))

    result := reflect.Zero(reflect.TypeOf(record))
    inter := result.Interface()
    fmt.Println("Result: ", reflect.TypeOf(result), ", Inter: ", reflect.TypeOf(inter))

    {
        err = json.Unmarshal(data, &result)
        require.NoError(t, err)
        fmt.Println(data, " was deserialized to ", result, "type: ", reflect.TypeOf(result))
        require.Equal(t, record, result)
    }
    {
        err = json.Unmarshal(data, &inter)
        require.NoError(t, err)
        fmt.Println(data, " was deserialized to ", inter, "type: ", reflect.TypeOf(inter))
        require.Equal(t, record, inter)
    }
}


type Person struct {
    FirstName  string
    LastName   string
    Age        uint8
}

func TestPersonMarshalling(t *testing.T) {
    CheckRoundTripJSON(t, Person{
        FirstName: "Leonard",
        LastName:  "Nimoy",
        Age:       84,
    })
}

Both code blocks will error. The first one leaves result default-initialized, and the second one makes inter point to a map containing the deserialized data.

I was wondering if there's a way to have provide this interface & functionality in Golang. I originally tried with result.Addr() but the result of Zero is not addressable, according to the documentation.





Aucun commentaire:

Enregistrer un commentaire