dqhbuwrwq692118284 2014-06-24 19:56
浏览 98
已采纳

流处理的异步测试

I'm very new to Go, so I may be misunderstanding something foundational about Go's async/stream handling, but here goes...

I'm trying to write some tests using ginkgo on a function I wrote that processes streams.

The processing side reads in newline-delimited text from a File until it encounters a special delimiter line at which point it tries to parse the text as JSON. The code looks like this:

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
}

My test looks something like this

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

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

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

Unfortunately, this yields a JSON parsing error, as it's trying to parse an empty string. I'm assuming that my problem is that I'm sending the string on the stream before I've told the ParseConfig() function to listen on that string for data? But I'm not entirely clear how I could refactor this to use proper go routines to first listen for data then send it.

Some of the potential solutions I saw were around the use of "channels" (with which I'm unfamiliar) but I was worried that this one need might not be worth a major refactor to introduce a whole new paradigm of concurrency.

Thanks!

  • 写回答

1条回答 默认 最新

  • dsgdhtr_43654 2014-06-24 20:24
    关注

    Not sure if I understood correctly, but your ParseConfig should probably take an io.Reader instead of a *os.File. That way you can test it directly without worrying about concurrency.

    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"}` + "
    |||
    ")
    
                    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")
    }
    

    file 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)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 cad图纸,chx-3六轴码垛机器人
  • ¥15 移动摄像头专网需要解vlan
  • ¥20 access多表提取相同字段数据并合并
  • ¥20 基于MSP430f5529的MPU6050驱动,求出欧拉角
  • ¥20 Java-Oj-桌布的计算
  • ¥15 powerbuilder中的datawindow数据整合到新的DataWindow
  • ¥20 有人知道这种图怎么画吗?
  • ¥15 pyqt6如何引用qrc文件加载里面的的资源
  • ¥15 安卓JNI项目使用lua上的问题
  • ¥20 RL+GNN解决人员排班问题时梯度消失