このblog postで説明されているパイプとフィルターのパターンを使用しています。パイプとフィルターのパターンを効果的にテストする方法
これを効果的にテストする方法が不思議です。私の考えは、各フィルタを個別にテストすることでした。たとえば、私は今の私のテストでこの
func watchTemperature(ctx context.Context, inStream <-chan int) {
maxTemp = 90
go func() {
for {
select {
case <-ctx.Done():
return
case temp := <-inStream:
if temp > maxTemp{
log.Print("Temperature too high!")
}
}
}
}()
}
のように見えるフィルタを持っている私は、ログが印刷されているかどうかを確認したいです。 私のテストは次のように見えます。
func TestWatchTemperature(t *testing.T) {
maxTemp = 90
ctx := context.Background()
inStream := make(chan int)
defer close(inStream)
watchTemperature(ctx, inStream)
var buf bytes.Buffer
log.SetOutput(&buf)
inStream<-maxTemp+1
logMsg := buf.String()
assert.True(t, strings.Contains(logMsg, "Temperature too high!"),
"Expected log message not found")
}
このフィルタは私のパイプラインの終わりであるとして、私は、このゴルーチン/フィルタは、すでに何かを行っているかどうかを判断するから読み取ることができますアウトチャネルを持っていません。
これまで私がオンラインで見つけたのは、テストでinStreamに書き込んだ後に数秒待ってからログを確認することでした。しかし、これは競争条件を導入してテストを遅くするので、これは本当に貧しい選択のようです。
このようなことをテストする最善の方法は何ですか?またはこのフィルタのデザインでテストするための良い方法はありません。いつもoutStreamが必要ですか?
これは私のアプローチを再考するように多くの助けになります。しかし、パイプラインパターンに関しては、結果を報告した後、ゴルーチンは停止/終了しません。したがって、結果チャンネルの権利と実際に違うわけではないステップが完了したことを報告しない限り、その方法で同期するのは難しいでしょうか? – FChris
チャンネルを使用して進捗状況/結果/完了を送信できます。あるいは、同じタイプ/ステップのすべてのワーカーが終了したときに、 'sync.WaitGroup'を使って通知を受け取ることができます。 –
goroutineを開始する関数のパラメータとしてオプションのチャネルを使用するのは一般的ですが、存在する場合は進捗状況の更新が行われ、存在しない場合は使用されません。 – FChris