-2

I was working through an example on marshalling and decided to get crafty with it. Was hoping I could have a generic interface reference passed in similar to the json.Unmarshall function and handle my other test cases by input instead of repeating the same code (yes, I'm coming from Java). Instead, I get back a map instead of a struct. It also appears I do not have a way to imply downwards what this 'type' of struct is.
Questions:

  1. How would I be able to get the appropriate struct type back?
  2. Is it even reasonable to take this approach of a utility method like this?

Code:
    //test 1 - simple dto
    var country models.Country
    var outCountry, errorCountry = attemptParse("Simple DTO", "./json/country.json", country)
    fmt.Println("Return - ", outCountry, " - ", errorCountry)
...
func attemptParse(test string, dataFile string, v interface{}) (interface{}, error){

    ...
    err := json.Unmarshal(data, &v)
    if err != nil {
        fmt.Println("Test - ", test, " - fail", err)
        return nil, err
    }

    fmt.Println("Test - ", test, " - result:")
    fmt.Println(v)
    return v, nil
}

Have also tried marshalling to nptr := reflect.New(reflect.TypeOf(v)), but this ended me with an address I could not resolve.
Output:

Test -  Simple DTO  - start
Test -  Simple DTO  - result:
map[Capital:Washington DC Continent:North America Name:USA]
Return -  map[Capital:Washington DC Continent:North America Name:USA]  -  <nil>
  • Pass pointer to `attemptParse`: `attemptParse("Simple DTO", "./json/country.json", &country)` Pass pointer value through to Unmarshal: `json.Unmarshal(data, v)`. I am writing a comment instead of an answer because this question has many duplicates, but I cannot find one at the moment. – Charlie Tumahai Jan 02 '22 at 02:13
  • 1
    See related questions: [Golang interface{} type misunderstanding](https://stackoverflow.com/q/38829941/5728991), [How to tell json.Unmarshal to use struct instead of interface](https://stackoverflow.com/q/44779319/5728991), [When unmarshaling JSON into interface{}, it becomes not needed type, but map](https://stackoverflow.com/q/65100543/5728991). –  Jan 02 '22 at 02:26

1 Answers1

0
  1. Try passing a pointer to the attemptParse() function:

    var outCountry, errorCountry = attemptParse("Simple DTO", "./json/country.json", &country)
    

    and change

    err := json.Unmarshal(data, &v)
    

    to

    err := json.Unmarshal(data, v)
    

    Please, see this playground for more details: https://go.dev/play/p/XEN5cZce0tG

  2. I'm not sure what exactly you are trying to test. But I would rather try table-driven tests first: https://dave.cheney.net/2019/05/07/prefer-table-driven-tests.

Andrey Dyatlov
  • 1,628
  • 1
  • 10
  • 12