I'm trying to unit test a function that will start a go routine and make sure this go routine panics in extreme circumstances (I pass in a mocked function that causes this). I'm not necessarily expecting this to actually occur in production but it's nice to have tests to cover this. The code is below:
// unit test
func TestPersistLogsPanic(t *testing.T) {
defer func() {
if r := recover(); r == nil {
t.Error("Error in log saver should cause PersistLogs to panic")
}
}()
go PersistLogs(hpq, lpq, mockPanicSaver)
hpq <- Log{}
time.Sleep(10 * time.Millisecond)
}
// function being tested
func PersistLogs(highPriorityChan chan Log, lowPriorityChan chan Log, saveFunc saver) {
var nextLog Log
for {
if len(highPriorityChan) > 0 {
nextLog = <-highPriorityChan
} else {
select {
case nextLog = <-highPriorityChan:
case nextLog = <-lowPriorityChan:
}
}
err := saveFunc(nextLog)
if err != nil {
panic(err)
}
}
}
// mock Saver function
func mockPanicSaver(_ Log) error {
return errors.New("Test log save error")
}
PersistLogs
waits for a Log
to come though either the hpq
or lpq
channels, then 'saves' the Log
using the function passed as the third param. This function populates a variable in PersistLogs
that later causes a panic (hope that makes sense).
The issue is that the call to recover
is outside the go routine that causes the panic. Are there any ways around this that people know of? Might be I'm doing this a strange way and others have a better idea - open to ideas!
Thanks in advance.