我正在尝试对将启动go例程的功能进行单元测试,并确保在极端情况下go例程会出现恐慌(我传入了导致该例程的模拟函数)。我不一定期望这会在生产中实际发生,但是可以通过测试来涵盖这一点很好。代码如下:
// 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
等待Log
通过hpq
或lpq
通道,然后使用作为传递的函数“保存” Log
。第三参数。此函数会在PersistLogs
中填充一个变量,此变量稍后会引起恐慌(希望如此)。
问题在于,对recover
的调用在导致恐慌的go例程之外。人们对此有什么解决的办法吗?可能是我正在以一种奇怪的方式这样做,而其他人有一个更好的主意-易于接受!
谢谢。