如何在go中模拟功能?

时间:2018-10-31 18:36:01

标签: go

package main

import (
    "net/http"
    "sync"
    "time"
)

type SessionInterface1 interface {
    doLoginAndReadDestinations1() bool
}

type Session1 struct {
    sessionCookie string
    mux           sync.Mutex
    sessionTime   time.Time
    targetAddress string
    currentJwt    string
    transport     *http.Transport
}

var currentSession1 Session1

func main() {

    currentSession1.verifyLogin1()

}

func (s *Session1) doLoginAndReadDestinations1() bool {
    ..logic...
    ... for example return true

}

func callDest1(si SessionInterface1) bool {
    return si.doLoginAndReadDestinations1()
}

func (s *Session1) verifyLogin1() bool {
    return callDest1(s)
}

我想创建单元测试并模拟doLoginAndReadDestinations1 我尝试为此方法创建接口并创建测试

func test1(t *testing.T) {
    type args struct {
    }
    tests := []struct {
        name string
        args args
        want bool
    }{{
        name: "test",
        args: args{},
        want: false,
    }}
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            var s1 *Session1
            count := 10
            s1 = &Session1{"", sync.Mutex{}, time.Now(), "", "", nil}

            var got1 = s1.verifyLogin()

            if got1 != tt.want {
                t.Errorf("getJwt() = %v, want %v", got, tt.want)
            }

        })
    }
}

我不知道如何在测试中更改doLoginAndReadDestinations1函数的逻辑并在第一个main中更改逻辑

2 个答案:

答案 0 :(得分:2)

在单元测试中,您仅在Session1上调用方法,而不在调用 Session1的方法上调用;所以没有什么可嘲笑的。使用模拟进行测试时,当那些类型是被测试类型的依赖项时,您不会模拟方法,而是模拟类型。例如,如果您有一个类型Foo依赖于类型Bar的(调用方法),并且想单独测试Foo,则可以创建一个{ {1}},并在对Bar的测试中,将其指定为Foo而不是BarMock。在您的真实代码中,您会给它真实的Bar。无法模拟一种类型的单个方法。

您可能会发现this StackOverflow question及其广泛的答案很有帮助。

答案 1 :(得分:2)

您将需要抽象要模拟的所有内容。不要将依赖关系作为具体的实现来解决,而要使用接口。然后,您将能够创建一个将实现此接口的模拟程序。

通常,我建议您stretchr/testify进行测试。它具有以下方法:

  1. 断言
  2. 需要
  3. 模拟
  4. 套房

该库将帮助您构建测试,编写测试并删除样板代码。 其内部具有嘲讽机制。在testify mock section

上了解有关模拟接口的信息