Как использовать интерфейс функции с реализацией diff - PullRequest
0 голосов
/ 31 октября 2018

Я использую interface, который я хочу макет один метод в этом function1 в тесте, и я не смог понять, как это лучше всего сделать для кода prod предоставит 1 значение и для теста предоставит некоторое фиктивное значение, может кто-нибудь привести пример? (Изм) это код:

https://play.golang.org/p/w367IOjADFV

package main

import (
    "fmt"
    "time"
)

type vInterface interface {
    function1() bool
}

type mStruct struct {
    info string
    time time.Time
}

func (s *mStruct) function1() bool {
    return true
}

func callSomething(si vInterface) bool {
    return si.function1()
}

func (s *mStruct) vl1() bool {
    s.time = time.Now()
    s.info = "vl1->info"
    return callSomething(s)
}

var currentVt1 mStruct

func main() {
    vl1 := currentVt1.vl1()

    fmt.Println(vl1)
}

Тест такой:

func Test_callSomething(t *testing.T) {
    type args struct {
        si vInterface
    }
    tests := []struct {
        name string
        args args
        want bool
    }{
        {
            name: "my tests",
            args: args{

            },
            want: false,
        },
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            if got := callSomething(tt.args.si); got != tt.want {
                t.Errorf("callSomething() = %v, want %v", got, tt.want)
            }
        })
    }
}

Но не уверен, как правильно его высмеивать ...

обновление

func Test_mStruct_vl1(t *testing.T) {
    type fields struct {
        info string
        time time.Time
    }
    tests := []struct {
        name   string
        fields fields
        want   bool
    }{
        {
            name: "some test",
            fields: struct {
                info string
                time time.Time
            }{info: "myinfo", time: time.Now() },

        },
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            s := &mStruct{
                info: tt.fields.info,
                time: tt.fields.time,
            }
            if got := s.vl1(); got != tt.want {
                t.Errorf("vl1() = %v, want %v", got, tt.want)
            }
        })
    }
}

1 Ответ

0 голосов
/ 31 октября 2018

Сначала вам нужен тип (любой тип), который реализует интерфейс vInterface. Вот простой пример:

type mockedVInterface struct {
    value bool
}

func (m mockedVInterface) function1() bool {
    return m.value
}

Это достаточно простая реализация, которой мы можем управлять: мы можем сказать, что должна возвращать ее функция function1(), просто установив это значение в поле value.

Этот тип mockedVInterface создан исключительно для целей тестирования, производственному коду это не нужно. Поместите его в тот же файл, где у вас есть тестовый код (поместите его перед Test_callSomething()).

А вот код тестирования:

func Test_callSomething(t *testing.T) {
    type args struct {
        si vInterface
    }
    tests := []struct {
        name string
        args args
        want bool
    }{
        {
            name: "testing false",
            args: args{
                si: mockedVInterface{value: false},
            },
            want: false,
        },
        {
            name: "testing true",
            args: args{
                si: mockedVInterface{value: true},
            },
            want: true,
        },
    }
    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            if got := callSomething(tt.args.si); got != tt.want {
                t.Errorf("callSomething() = %v, want %v", got, tt.want)
            }
        })
    }
}

Обратите внимание, что в этом простом случае мы могли бы также использовать простой неструктурный тип, который имеет bool в качестве базового типа, например:

type mockedVInterface bool

func (m mockedVInterface) function1() bool {
    return bool(m)
}

И это работает, и тестирование кода также проще:

tests := []struct {
        name string
        args args
        want bool
    }{
        {
            name: "testing false",
            args: args{
                si: mockedVInterface(false),
            },
            want: false,
        },
        {
            name: "testing true",
            args: args{
                si: mockedVInterface(true),
            },
            want: true,
        },
    }

Но это работает только в том случае, если в макетируемом интерфейсе есть одна функция с одним возвращаемым значением. В общем случае требуется структура.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...