Как смоделировать метод, который возвращает структуру?

Вот немного golang программа, которая подключается к localhost через ssh и делает некоторые sftp подобные операции. Работает нормально но хотелось бы сделать doTheWork() функция более тестируема.

Я прочитал об использовании gomock для создания макетов для интерфейсов. Итак, я уже создал два интерфейса, Sftper а также Walker и я использую их вместо вызова sftp Методы напрямую.

То, что я хочу сделать, это макет всех вещей из stfp внутри doTheWork(), Close() это просто, потому что он возвращает только error (или же nil). Но Create() возвращает * sftp.File, и это структура, а не интерфейс. То же самое с Walk() который возвращает другую структуру. Я должен был бы создать одну из этих структур в моем тестовом коде, и это на самом деле невозможно без фактического вызова реального sftp библиотека и создание удаленного подключения и создание удаленного файла, и это именно то, что я пытаюсь макетировать.

Что мне не хватает?

package main

import (
    "log"
    "os"

    "github.com/kr/fs"
    "github.com/pkg/sftp"
    "golang.org/x/crypto/ssh"
)

// Sftper helps make things testable
type Sftper interface {
    Close() error
    Create(path string) (*sftp.File, error)
    Lstat(p string) (os.FileInfo, error)
    Walk(root string) *fs.Walker
}

// Walker helps make things testable
type Walker interface {
    Step() bool
    Err() error
    Path() string
}

var sftpclient Sftper
var w Walker

func doTheWork(sftpclient Sftper) {
    defer sftpclient.Close()

    // walk a directory
    w = sftpclient.Walk("/tmp/")
    for w.Step() {
        if w.Err() != nil {
            continue
        }
        log.Println(w.Path())
    }

    // leave your mark
    f, err := sftpclient.Create("hello.txt")
    if err != nil {
        log.Fatal(err)
    }
    if _, err1 := f.Write([]byte("Hello world!")); err1 != nil {
        log.Fatal(err1)
    }

    // check it's there
    fi, err := sftpclient.Lstat("hello.txt")
    if err != nil {
        log.Fatal(err)
    }
    log.Println(fi)

}

func main() {
    config := &ssh.ClientConfig{
        User: "myusername",
        Auth: []ssh.AuthMethod{
            ssh.Password("mysupersecretpassword"),
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }
    conn, err0 := ssh.Dial("tcp", "localhost:22", config)
    if err0 != nil {
        log.Fatal("Failed to dial: ", err0)
    }

    // open an SFTP session over an existing ssh connection.
    var err error
    sftpclient, err = sftp.NewClient(conn)
    if err != nil {
        log.Fatal(err)
    }
    doTheWork(sftpclient)
}

0 ответов

Другие вопросы по тегам