Ich verwende die Rohre und Filter Muster wie in diesem blog post beschrieben.Wie effektiv die Rohre und Filter Muster
Ich frage mich, wie man das effektiv testen kann. Meine Idee war, jeden Filter unabhängig voneinander zu testen. Zum Beispiel habe ich einen Filter, wie diese mag ich nur für jetzt
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!")
}
}
}
}()
}
In meinem Test überprüft, ob das Protokoll gedruckt wurde. Mein Test sieht wie folgt aus.
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")
}
Da diese Filter das Ende meiner Pipeline ist, habe ich nicht einen aus Kanal habe ich aus lesen kann, um zu bestimmen, ob diese goroutine/Filter bereits etwas getan hat.
Das Einzige, was ich bisher online gefunden habe, war, nach dem Schreiben in den inStream in meinem Test nur ein paar Sekunden zu warten und dann das Protokoll zu überprüfen. Jedoch scheint dies eine wirklich schlechte Wahl zu sein, da es einfach eine Rennbedingung einführt und den Test verlangsamt.
Was ist der beste Weg, um so etwas zu testen oder gibt es einfach keine gute Möglichkeit, es mit diesem Design meines Filters zu testen und ich brauche immer einen outStream?
Dies hilft viel, da es mich dazu bringt, meinen Ansatz zu überdenken. In Bezug auf das Pipeline-Muster stoppt/beendet die Goroutine jedoch nicht, nachdem ein Ergebnis gemeldet wurde. Es wäre also schwierig, auf diese Weise zu synchronisieren, wenn ich nicht melde, dass ein Schritt abgeschlossen wurde, der sich nicht wirklich von einem Ergebniskanal unterscheidet, oder? – FChris
Sie können Kanäle verwenden, um Fortschritt/Ergebnis/Vervollständigung zu senden. Oder Sie können 'sync.WaitGroup' verwenden, um benachrichtigt zu werden, wenn alle Worker des gleichen Typs/Schritts fertig sind. –
Ist es üblich, einen optionalen Kanal als Parameter für Funktionen zu haben, die goroutines initiieren, auf die Fortschrittsaktualisierungen geschrieben werden, wenn sie vorhanden sind und die nicht verwendet werden, wenn sie nicht bereitgestellt werden? – FChris