我有以下功能:
func ObtainTranslationStringsFile(path string) ([]string, error) {
if contents, err := ioutil.ReadFile(path); err != nil {
return ObtainTranslationStrings(string(contents))
} else {
return nil, err
}
}
Run Code Online (Sandbox Code Playgroud)
我需要模拟ioutil.ReadFile,但我不知道该怎么做.可能吗?
mat*_*mc3 12
如果你想嘲笑这个,有几种方法可以解决这个问题.第一个也许是最简单的是改变使用ioutil.ReadFile,而是调用带有 io.Reader接口的ioutil.ReadAll.按照这种方法注入自己的io.Reader /文件系统实现非常容易.
如果您不想更改方法签名,则另一个选项是不使用ioutil
,而是声明ReadFile的函数替换.使用对象方法而不是函数注入更容易,但它是可行的.它只依赖于包级别变量魔法,这对某些人来说可能看起来很令人反感.请参阅下面介绍的选项:
package main
import (
"bytes"
"fmt"
"io"
"io/ioutil"
_ "log"
)
type ReadFile func(filename string) ([]byte, error)
// myReadFile is a function variable that can be reassigned to handle mocking in option #2
var myReadFile = ioutil.ReadFile
type FakeReadFiler struct {
Str string
}
// here's a fake ReadFile method that matches the signature of ioutil.ReadFile
func (f FakeReadFiler) ReadFile(filename string) ([]byte, error) {
buf := bytes.NewBufferString(f.Str)
return ioutil.ReadAll(buf)
}
func main() {
payload := "PAYLOAD"
path := "/dev/nul"
buf := bytes.NewBufferString(payload)
// option 1 is more elegant, but you have to change the method signature to take an io.Reader
result1, err := ObtainTranslationStringsFileChoice1(buf)
fmt.Printf("ObtainTranslationStringsFileChoice1 == %#v, %#v\n", result1, err)
// option 2 keeps the method signature, but allows you to reassign a the myReadFile variable to change the method behavior for testing
fake := FakeReadFiler{Str: payload}
myReadFile = fake.ReadFile
result2, err := ObtainTranslationStringsFileChoice2(path)
fmt.Printf("ObtainTranslationStringsFileChoice2 == %#v, %#v\n", result2, err)
}
func ObtainTranslationStringsFileChoice1(rdr io.Reader) ([]string, error) {
if contents, err := ioutil.ReadAll(rdr); err == nil {
return []string{string(contents)}, nil
} else {
return nil, err
}
}
func ObtainTranslationStringsFileChoice2(path string) ([]string, error) {
if contents, err := myReadFile(path); err == nil {
return []string{string(contents)}, nil
} else {
return nil, err
}
}
Run Code Online (Sandbox Code Playgroud)
这里的游乐场版本:沙箱.
如果你想变得更复杂,我建议制作一个完整的文件系统模拟.这就是我通常所做的事情,并不像听起来那么困难:https://talks.golang.org/2012/10things.slide#8.在您的示例中,您没有使用结构和接口,这使得这种模拟更加强大.
and*_*olm -4
别嘲笑ioutil.ReadFile
。一旦你嘲笑了它,测试ObtainTranslationStringsFile
就不会比测试更多ObtainTranslationStrings
。如果需要测试ObtainTranslationStringsFile
,请创建一个临时文件并将其路径传递给ObtainTranslationStringsFile
. 这样您将实际测试该函数添加的功能。