Как смоделировать метод, который возвращает структуру?
Вот немного 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)
}