0

我对 Go 很陌生,所以我可能会误解 Go 的异步/流处理的一些基础知识,但是这里有......

我正在尝试在我编写的处理流的函数上使用银杏编写一些测试。

处理端从文件中读取以换行符分隔的文本,直到遇到一个特殊的分隔符行,此时它会尝试将文本解析为 JSON。代码如下所示:

func ParseConfig(inStream *os.File) (Config, error){
  var header string

  var stdin = bufio.NewScanner(inStream)
  for stdin.Scan() {
    line := stdin.Text()

    if line == "|||" {
      break;
    }

    header += line
  }

  // parse JSON here and return
}

我的测试看起来像这样

Describe("ParseConfig()", func() {
  It("should pass for a valid header", func(){
    _, err := io.WriteString(stream, "{\"Key\": \"key\", \"File\": \"file\"}\n|||\n")
    Expect(err).NotTo(HaveOccurred())

    conf, err := parser.ParseConfig(stream)
    Expect(err).NotTo(HaveOccurred())

    Expect(conf.Key).To(Equal("key"))
  })
})

不幸的是,这会产生一个 JSON 解析错误,因为它试图解析一个空字符串。我假设我的问题是我在告诉 ParseConfig() 函数在该字符串上侦听数据之前在流上发送字符串?但我并不完全清楚如何重构它以使用正确的 go 例程首先侦听数据然后发送它。

我看到的一些潜在解决方案是围绕“通道”的使用(我不熟悉),但我担心这一需求可能不值得进行重大重构以引入全新的并发范式。

谢谢!

4

1 回答 1

2

不确定我是否理解正确,但您的 ParseConfig 可能应该使用 aio.Reader而不是*os.File. 这样您就可以直接对其进行测试,而不必担心并发性。

文件 t_test.go:

package main

import (
        "strings"
        "testing"

        "github.com/onsi/ginkgo"
        "github.com/onsi/gomega"
)

var _ = ginkgo.Describe("ParseConfig()", func() {
        ginkgo.It("should pass for a valid header", func() {
                // really don't know what you were doing with your 'stream' variable
                // This is a test, you should forge a test scenario and pass it to your config function
                stream := strings.NewReader(`{"Key": "key", "File": "file"}` + "\n|||\n")

                conf, err := ParseConfig(stream)
                gomega.Expect(err).NotTo(gomega.HaveOccurred())
                gomega.Expect(conf.Key).To(gomega.Equal("key"))
        })
})

func TestParseConfig(t *testing.T) {
        ginkgo.RunSpecs(t, "Parse Config")
}

文件 main.go

package main

import (
        "bufio"
        "encoding/json"
        "io"
        "log"
        "os"
)

type Config struct {
        Key  string
        File string
}

func ParseConfig(inStream io.Reader) (*Config, error) {
        var header string

        var stdin = bufio.NewScanner(inStream)
        for stdin.Scan() {
                line := stdin.Text()

                if line == "|||" {
                        break
                }
                header += line
        }

        c := &Config{}

        // parse JSON here and return
        if err := json.Unmarshal([]byte(header), c); err != nil {
                return nil, err
        }
        return c, nil
}

func main() {
        f, err := os.Open("config.json")
        if err != nil {
                log.Fatal(err)
        }
        ParseConfig(f)
}
于 2014-06-24T20:24:12.457 回答