用于测试的内存文件

时间:2016-10-29 04:35:47

标签: unit-testing go

如何在Go中为单元测试创​​建内存文件?

在Python中,我使用io.BytesIOio.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

3 个答案:

答案 0 :(得分:13)

您可以使用Buffer

通常,在代码中使用io.Readerio.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()之类的事情很有用。