doujingqu3030
2018-03-08 20:33
浏览 144
已采纳

Golang-解析yaml文件并检查对象的单元测试

I want to test parse of yaml and test it via unit test I’ve create structs that with appropriate types but the assertion is always falid, I try with the following code which failed constantly

This is the yaml content which is valid (maybe with the copy it changed but I was able to parse it correctly)

ID: demo
version: 0.0.5

dep:
 - name: db
   path: mtb
   requires:
    - name: vi_db


 - name: srv
   path: srv1
   properties:
     LOG_LEVEL: "info"


   parameters:
     mem: 12G
   requires:
     - name: db
       properties:

This is the test I was created

    func Test_parseFile(t *testing.T) {

        yamlfile, err := ioutil.ReadFile("./testdata/file.yaml")

        type Properties map[string]string
        type Parameters map[string]interface{}

        type Modules struct {
            Name string
            Path string `yaml:"path,omitempty"`
            Requires   []Requires `yaml:"requires,omitempty"`
            Properties Properties `yaml:"properties,omitempty"`
        }

   type Requires struct {
      Name       string     `yaml:"name,omitempty"`
      Properties Properties `yaml:"properties,omitempty"`
    }



    type args struct {
        contentFile []byte
    }


     tests := []struct {
            name        string
            args        args
            wantOut     Properties
            wantNoTests bool
            wantErr     bool
        }{
            {
                name: "test",
                args: args{
                    contentFile: yamlfile,
                },

                wantOut: Modules{
                    Name: "srv",
                    Path: "srv1",

                    Properties{
                        "LOG_LEVEL":       "info",
                        "DEBUG_LOG_LEVEL": "ALL",
                    },
                    Parameters:{
                        "mem":"12G",
                    },
                    Requires: {
                        name: "db",
                        Properties{
                            "CONFIG": '[tomcontext.xml:
                            {"service_nameDB" : "~{con-name}"}]'   
                        },
                    },
                },

                wantNoTests: true,
                wantErr:     true,
            },
        }

This is the assertion code

for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {

            gotOut := ParseFile(tt.args.contentFile)


            if !reflect.DeepEqual(gotOut.Modules[1], tt.wantOut) {

                t.Errorf("parseFile() = %v, want %v", gotOut.Modules[2], tt.wantOut)
            }

The error is :

parseFile() = map[], want map[LOG_LEVEL:info DEBUG_LOG_LEVEL:ALL]

How should I overcome it to check the module properties ?

The ParseFile method is just err := yaml.Unmarshal([]byte(yamlFile), &yamlconent)

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dongzhi6927 2018-03-31 09:48
    已采纳

    I'm not entirely certain what the question is but I managed to get your test to work like this:

    package sandbox
    
    import (
        "testing"
    
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/require"
        "gopkg.in/yaml.v2"
    )
    
    type Properties map[string]string
    type Parameters map[string]interface{}
    
    type Requires struct {
        Name       string     `yaml:"name,omitempty"`
        Properties Properties `yaml:"properties,omitempty"`
    }
    
    type Module struct {
        Name       string
        Path       string     `yaml:"path,omitempty"`
        Requires   []Requires `yaml:"requires,omitempty"`
        Properties Properties `yaml:"properties,omitempty"`
        Parameters Parameters `yaml:"parameters,omitempty"`
    }
    
    type File struct {
        Modules []Module
    }
    
    func Test_ParseFile(t *testing.T) {
        input := []byte(`ID: demo
    version: 0.0.5
    
    modules:
     - name: db
       path: mtb
       requires:
        - name: vi_db
    
    
     - name: srv
       path: srv1
       properties:
         LOG_LEVEL: "info"
         DEBUG_LOG_LEVEL : ALL
       parameters:
         mem: 12G
       requires:
         - name: db
           properties:
                CONFIG: '[tomcontext.xml:
                  {"service_nameDB" : "~{con-name}"}]'`)
    
        tests := []struct {
            name    string
            wantOut Module
        }{
            {
                name: "test",
    
                wantOut: Module{
                    Name: "srv",
                    Path: "srv1",
    
                    Properties: Properties{
                        "LOG_LEVEL":       "info",
                        "DEBUG_LOG_LEVEL": "ALL",
                    },
                    Parameters: Parameters{
                        "mem": "12G",
                    },
                    Requires: []Requires{
                        {
                            Name: "db",
                            Properties: Properties{
                                "CONFIG": `[tomcontext.xml: {"service_nameDB" : "~{con-name}"}]`,
                            },
                        },
                    },
                },
            },
        }
    
        for _, tt := range tests {
            t.Run(tt.name, func(t *testing.T) {
                actual, err := ParseFile(input)
                require.NoError(t, err)
                require.NotNil(t, actual)
                require.Len(t, actual.Modules, 2)
                assert.Equal(t, tt.wantOut, actual.Modules[1])
            })
        }
    }
    
    func ParseFile(yamlFile []byte) (File, error) {
        var f File
        err := yaml.Unmarshal(yamlFile, &f)
        return f, err
    }
    

    Note that I imported https://github.com/stretchr/testify to make tests a bit easier. Of course you could replace this with your original reflect.DeepEquals check. Testify is useful here because it will print a useful diff in case the expectation is not met.

    打赏 评论

相关推荐 更多相似问题