mercredi 4 juillet 2018

Learning to Write Unit-Tests

I am trying to learn how to write tests for my code in order to write better code, but I just seem to have the hardest time figuring out how to actually test some code I have written. I have read so many tutorials, most of which seem to only cover functions that add two numbers or mock some database or server.

I have a simple function I wrote below that takes a text template and a CSV file as input and executes the template using the values of the CSV. I have "tested" the code by trial and error, passing files, and printing values, but I would like to learn how to write proper tests for it. I feel that learning to test my own code will help me understand and learn faster and better. Any help is appreciated.

// generateCmds generates configuration commands from a text template using
// the values from a CSV file. Multiple commands in the text template must
// be delimited by a semicolon. The first row of the CSV file is assumed to
// be the header row and the header values are used for key access in the
// text template.
func generateCmds(cmdTmpl string, filename string) ([]string, error) {
    t, err := template.New("cmds").Parse(cmdTmpl)
    if err != nil {
        return nil, fmt.Errorf("parsing template: %v", err)
    }

    f, err := os.Open(filename)
    if err != nil {
        return nil, fmt.Errorf("reading file: %v", err)
    }
    defer f.Close()

    records, err := csv.NewReader(f).ReadAll()
    if err != nil {
        return nil, fmt.Errorf("reading records: %v", err)
    }
    if len(records) == 0 {
        return nil, errors.New("no records to process")
    }

    var (
        b    bytes.Buffer
        cmds []string
        keys = records[0]
        vals = make(map[string]string, len(keys))
    )

    for _, rec := range records[1:] {
        for k, v := range rec {
            vals[keys[k]] = v
        }
        if err := t.Execute(&b, vals); err != nil {
            return nil, fmt.Errorf("executing template: %v", err)
        }
        for _, s := range strings.Split(b.String(), ";") {
            if cmd := strings.TrimSpace(s); cmd != "" {
                cmds = append(cmds, cmd)
            }
        }
        b.Reset()
    }
    return cmds, nil
}

Aucun commentaire:

Enregistrer un commentaire