Асинхронное тестирование с потоковой обработкой

Я очень новичок в Go, поэтому, возможно, я неправильно понимаю что-то фундаментальное в асинхронной/потоковой обработке Go, но вот...

Я пытаюсь написать несколько тестов, используя ginkgo для написанной мной функции, которая обрабатывает потоки.

Сторона обработки читает текст с разделителями новой строки из файла до тех пор, пока не встретит специальную строку-разделитель, после чего она попытается проанализировать текст как 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, чтобы сначала прослушивать данные, а затем отправлять их.

Некоторые из потенциальных решений, которые я видел, были связаны с использованием «каналов» (с которыми я не знаком), но я был обеспокоен тем, что эта потребность может не стоить серьезного рефакторинга для введения совершенно новой парадигмы параллелизма.

Спасибо!


person Jeff Allen    schedule 24.06.2014    source источник
comment
Ваш пример очень далек от компиляции. Пожалуйста, приведите пример, который хотя бы компилируется. Где ваш «поток» io.Writer (который вы передаете io.WriteString)?   -  person creack    schedule 25.06.2014


Ответы (1)


Не уверен, правильно ли я понял, но ваш ParseConfig, вероятно, должен принимать io.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)
}
person creack    schedule 24.06.2014
comment
Идеальный! Большое спасибо, что нашли время. - person Jeff Allen; 25.06.2014