如何在Go中为单元测试创建内存文件?
在Python中,我使用io.BytesIO
或io.StringIO
测试文件读取或写入文件。例如,要测试文件解析器,我会有
def test_parse_function():
infile = io.StringIO('''\
line1
line2
line3
''')
parsed_contents = parse_function(infile)
expected_contents = ['line1', 'line2', 'line3'] # or whatever is appropriate
assert parsed_contents == expected_contents
同样对于文件输出,我会有以下内容:
def test_write_function():
outfile = io.StringIO()
write_function(outfile, ['line1', 'line2', 'line3'])
outfile.seek(0)
output = outfile.read()
expected_output = '''\
line1
line2
line3
'''
assert output == expected_output
答案 0 :(得分:13)
您可以使用Buffer。
通常,在代码中使用io.Reader和io.Writer接口(Buffer实现两者)来处理IO是个好主意。这样你就可以用同样的方式处理各种输入/输出方法(本地文件,内存缓冲区,网络连接......),而不知道你正在使用的特定函数中处理什么。它使它更抽象,使测试变得微不足道。
使用简单函数的示例:
功能定义:
// mypkg project mypkg.go
package mypkg
import (
"bufio"
"io"
"strings"
)
func MyFunction(in io.Reader, out io.Writer) {
rd := bufio.NewReader(in)
str, _ := rd.ReadString('\n')
io.WriteString(out, strings.TrimSuffix(str, "\n")+" was input\n")
}
程序中的功能使用:
package main
import (
"mypkg"
"os"
)
func main() {
mypkg.MyFunction(os.Stdin, os.Stdout)
}
测试:
// mypkg project mypkg_test.go
package mypkg
import (
"bytes"
"testing"
)
func TestMyFunction(t *testing.T) {
ibuf := bytes.NewBufferString("hello\n")
obuf := bytes.NewBufferString("")
MyFunction(ibuf, obuf)
if obuf.String() != "hello was input\n" {
t.Fail()
}
}
答案 1 :(得分:3)
如" Pragmatic and Effective Testing in Go"中所述,您可以使用spf13/afero
进行文件抽象,从而简化测试。
该图书馆有Using Afero for Testing:
使用模拟文件系统进行测试有很大好处。
每次初始化时都处于完全空白状态,无论操作系统如何,都可以轻松重现 您可以根据内容创建文件,文件访问速度快,同时还可以避免因删除临时文件,Windows文件锁定等所有烦人的问题。
MemMapFs后端非常适合测试。
- 比在磁盘上执行I / O操作快得多
- 避免安全问题和权限
- 更多控制。 '
rm -rf /
'有信心- 测试设置要容易得多
- 不需要进行测试清理
它使用fully atomic memory backed filesystem (MemMapFs
)
它是完全并发的,可以在安全的日常工作中使用。
答案 2 :(得分:2)
如果您需要findViewById(R.id.signInButton).setOnClickListener(new View.OnClickListener()
{ @Override public void onClick(View v) { signIn(); }});
findViewById(R.id.signOutButton).setOnClickListener(new View.OnClickListener()
{ @Override public void onClick(View v) { signOut(); }});
findViewById(R.id.keyTestButton).setOnClickListener(new View.OnClickListener()
{ @Override public void onClick(View v) { decryptThisTest(); }});
findViewById(R.id.getBkTicksButton).setOnClickListener(new View.OnClickListener()
{ @Override public void onClick(View v) { getBookTickers(); }});
findViewById(R.id.getBalsButton).setOnClickListener(new View.OnClickListener()
{ @Override public void onClick(View v) { getBalances(); }});
,并且不需要写访问权限,请使用bytes.Reader
:
io.ReadSeeker
这对于诸如http.ServeContent()
之类的事情很有用。