如何重新定义/模拟Go中的方法以进行测试?

时间:2016-07-04 07:19:20

标签: unit-testing testing go

我正在为Go库创建测试。而且我发现了一个错误:

  

无法分配到

我有以下代码(https://play.golang.org/p/kf0gANb-p-):

package main

import (
    "bytes"
    "fmt"

    "os/exec"
    "strconv"
    "strings"

)
const (
    CONSOLE         = "dialog"
    KDE             = "kdialog"
    GTK             = "gtkdialog"
    X               = "Xdialog"
    DIALOG_TEST_ENV = "test_env"
    AUTO            = "auto"
)

const (
    DIALOG_ERR_CANCEL = "exit status 1"
    DIALOG_ERR_HELP   = "exit status 2"
    DIALOG_ERR_EXTRA  = "exit status 3"
)
type Dialog struct {
    environment string
    parentId    int
    title       string
    backtitle   string
    label       string
    height      int
    width       int
    left        int
    top         int
    shadow      bool
    helpButton  bool
    helpLabel   string
    extraLabel  string
    cancelLabel string
    okLabel     string
    beforeDtype []string
    beforeSize  []string
    afterSize   []string
    lastCmd     []string
}

func (d *Dialog) Yesno() bool {
    if _, err := d.exec("yesno", true); err != nil {
        if err.Error() == DIALOG_ERR_CANCEL {
            return false
        }
    }
    return true
}

func NewTestDialogRAW(environment string, parentId int) Dialog {
    var res = new(Dialog)
    LastCMD = []string{}
    return *res
}
func (d *Dialog) exec(dType string, allowLabel bool) (string, error) {
    var arg string
    cmd := exec.Command(d.environment)

    if d.okLabel != "" {
        cmd.Args = append(cmd.Args, "--ok-label", d.okLabel)
    }
    if d.extraLabel != "" {
        cmd.Args = append(cmd.Args, "--extra-button")
        cmd.Args = append(cmd.Args, "--extra-label", d.extraLabel)
    }
    if d.helpButton {
        cmd.Args = append(cmd.Args, "--help-button")
        if d.helpLabel != "" {
            cmd.Args = append(cmd.Args, "--help-label", d.helpLabel)
        }
    }
    if d.shadow == false {
        cmd.Args = append(cmd.Args, "--no-shadow")
    }
    if d.backtitle != "" {
        cmd.Args = append(cmd.Args, "--backtitle", d.backtitle)
    }
    if d.cancelLabel != "" {
        cmd.Args = append(cmd.Args, "--cancel-label", d.cancelLabel)
    }
    if d.title != "" {
        cmd.Args = append(cmd.Args, "--title", d.title)
    }
    for _, arg := range d.beforeDtype {
        cmd.Args = append(cmd.Args, arg)
    }
    cmd.Args = append(cmd.Args, "--"+dType)

    if allowLabel == true {
        cmd.Args = append(cmd.Args, d.label)
    }
    for _, arg = range d.beforeSize {
        cmd.Args = append(cmd.Args, arg)
    }
    if d.environment != KDE {
        cmd.Args = append(cmd.Args, strconv.Itoa(d.height))
        cmd.Args = append(cmd.Args, strconv.Itoa(d.width))
    }
    for _, arg = range d.afterSize {
        cmd.Args = append(cmd.Args, arg)
    }
    if d.environment == CONSOLE {
        cmd.Args = append(cmd.Args, "--stdout")
    } else {
        cmd.Args = append(cmd.Args, "--attach")
        cmd.Args = append(cmd.Args, strconv.Itoa(d.parentId))
    }

    var out bytes.Buffer
    cmd.Stdout = &out
    var err error
    if d.environment != DIALOG_TEST_ENV {
        err = cmd.Run()
    }
    d.lastCmd = cmd.Args

    //d.reset()
    return strings.Trim(out.String(), "\r\n "), err
}



func main() {
var tests = []bool{true, false}
for _,expected_val := range tests {
    fmt.Println("Hello, playground ",expected_val )
    }
}

我试过测试它,但我不知道如何重新定义该方法?

main_test.go:

import (
    "fmt"
    "testing"
)
func TestYesNo(t *testing.T) {
    d := NewTestDialogRAW(DIALOG_TEST_ENV, 0)
    d.Yesno()
    x := LastCMD
    expected_str := "[ --no-shadow --yesno  0 0 --attach 0]"
    if fmt.Sprintf("%v", x) != expected_str {
        t.Errorf("Expected %v, actual %v ", expected_str, x)
    }
    f := func(dType string, allowLabel bool) (string, error) {
        return "", fmt.Errorf(DIALOG_ERR_CANCEL)
    }
    d.exec = f    
}

去测试./ ... -v

# _/root/Development/git-repos/go-dialog
./dialog_test.go cannot assign to d.exec
FAIL    _/root/Development/git-repos/go-dialog [build failed]

1 个答案:

答案 0 :(得分:1)

d.exec不是struct声明的一部分(它不是struct字段)。它是在对话框类型上定义的方法。因此它不可寻址且无法分配。

您可以尝试在新类型中嵌入Dialog并重新定义该类型的exec

type TestDialog struct {
    Dialog
}

func (d *TestDialog) exec(dType string, allowLabel bool) (string, error) {
    return "", fmt.Errorf(DIALOG_ERR_CANCEL)
}