猿问

运行测试用例时,模拟方法在 golang 中不起作用

我试图在测试用例中模拟一个结构方法,但它不起作用。我想在这里模拟Validate方法:`


package main


import (

    "fmt"

)


type DemoInterface interface {

    Inc(int) (int, error)

    Validate(int) error

}

type DemoStruct struct{}


func (l DemoStruct) Inc(num int) (int, error) {

    err := l.Validate(num)

    if err != nil {

        return 0, err

    }

    num = num + 100

    return num, nil


}

func (l DemoStruct) Validate(num int) error {// SOME DB LOGIC IS HERE WHICH I CAN NOT POST at Stackoverflow

    if num > 100 {

        return fmt.Errorf("INVALID NUM %v", num)

    }

    return nil

}


func main() {

    s, err := DemoStruct{}.Inc(10)

    if err != nil {

        fmt.Println(err)

    }

    fmt.Println(s)


}

`


我的测试用例:


package main


import (

    "fmt"

    "testing"

)


const (

    SUCCESS = "SUCCESS"

    ERROR   = "ERROR"

)


type MockDemoStruct struct {

    DemoStruct

    functionality string

}


func (m MockDemoStruct) Validate(num int) error {

    switch m.functionality {

    case SUCCESS:

        return nil

    case ERROR:

        fmt.Errorf("MOCK ERROR %v", num)


    }

    return fmt.Errorf("MOCK ERROR %v", num)

}


func TestPath(t *testing.T) {


    t.Run("ERROR", func(t *testing.T) {

        ls := MockDemoStruct{DemoStruct{}, ERROR}

        res, err := ls.Inc(110)

        expected := fmt.Errorf("MOCK ERROR %v", 10)

        if err != expected {

            t.Errorf("NOT MATCH  %v  %v", err, expected)

            //NOT MATCH  INVALID NUM 110  MOCK ERROR 10


        }

        fmt.Println(res)

    })

}

这里没有调用MockDemoStruct.Validate 。我从 Validate 得到INVALID NUM 110,但它应该是MOCK ERROR 110


摇曳的蔷薇
浏览 176回答 3
3回答

POPMUISE

在这种情况下,Inc中的方法DemoStruct调用l.Validatel 是 a的方法DemoStruct。该方法的接收者明确地是一个DemoStruct. 所以MockDemoStruct.Validate不会调用该方法。Go 没有您在代码中假设的继承。您不能覆盖DemoStruct. MockDemoStruct组成DemoStruct. _ 为了实际测试这个方法,我建议传递DemoStruct一个 db 接口,它可以在你的测试中被模拟。

智慧大石

为了使该方法可模拟,我们将不得不使用基于 DI(依赖注入)的代码模式。**We can mock only those methods which are injectable**.我们有两个选项可以在此代码中引入依赖注入。在界面的帮助下使用委托设计模式使用函数作为类型引入 Monkey 修补使用接口委托:type Deligation interface {    Validate(num int) error}type DemoStruct struct {    delegate Deligation}func (DemoStruct) Validate(num int) error {    if num > 100 {        return fmt.Errorf("INVALID NUM %v", num)    }    return nil}func (l DemoStruct) Inc(num int) (int, error) {    err := l.delegate.Validate(num) // Call method using delegate    if err != nil {        return 0, err    }    num = num + 100    return num, nil}func main() {    s, err := DemoStruct{delegate: DemoStruct{}}.Inc(10) // assign delegate inside DemoStruct    if err != nil {        fmt.Println(err)    }    fmt.Println(s)}使用猴子补丁:func Validate(num int) error {    if num > 100 {        return fmt.Errorf("INVALID NUM %v", num)    }    return nil}type DemoStruct struct {    Validate func(num int) error //  function as a type}func (l DemoStruct) Inc(num int) (int, error) {    err := l.Validate(num)// It can be replaced in test cases.    if err != nil {        return 0, err    }    num = num + 100    return num, nil}func main() {    s, err := DemoStruct{Validate: Validate}.Inc(10) // assign Validate inside DemoStruct    if err != nil {        fmt.Println(err)    }    fmt.Println(s)}

一只斗牛犬

我认为你还需要为'MockDemoStruct'实现'Inc'接收器,在这里你试图过度使用结构的继承属性,看起来GO不支持。
随时随地看视频慕课网APP

相关分类

Go
我要回答