2014-10-12 69 views
1

我試圖測試接受類型爲「error」的參數的函數。該功能應該在某些情況下恐慌,我試圖測試場景。使用反射調用具有nil參數的函數會導致「使用零值參數調用」恐慌

然而,當我嘗試在nil值(可以傳遞到接受型「錯誤」的一些功能)使用reflect.Call,似乎導致以下消息恐慌:

reflect: Call using zero Value argument 

我發現了以下帖子,但我沒有將它集成到我的函數中。

相關轉到遊樂場:http://play.golang.org/p/cYQMQ6amPH

在上面的操場上,我想調用InvocationCausedPanic(PanicOnErr, nil)從返回false,然而,上述恐慌反映是造成假陽性。

是否有任何修改,我可以對InvocationCausedPanicinvoke功能,使這項工作(同時保留其測試不能接受nil作爲參數等功能的能力 - 接受例如一個字符串的函數)?

也許問題在於如何調用函數?

我已經把InvocationCausedPanic(PanicOnErr, new(error))InvocationCausedPanic(PanicOnErr, error(nil))這樣的東西都沒有用。

感謝您的任何建議。

回答

3

如果參數值爲零,則使用函數參數類型的零值。

if paramValue == nil { 
     reflectedParams[paramIndex] = reflect.New(expectedType).Elem() 
    } else { 
     reflectedParams[paramIndex] = reflect.ValueOf(paramValue) 
    } 

playground

,如果你計算反映值,然後檢查可轉讓性,您可以簡化代碼。通過此更改,compatible功能不是必需的。

for paramIndex, paramValue := range params { 
    if paramValue == nil { 
     reflectedParams[paramIndex] = reflect.New(expectedType).Elem() 
    } else { 
     reflectedParams[paramIndex] = reflect.ValueOf(paramValue) 
    } 
    expectedType := funcType.In(paramIndex) 
    actualType := reflectedParams[paramIndex].Type() 
    if !actualType.AssignableTo(expectedType) { 
     errStr := fmt.Sprintf("InvocationCausedPanic called with a mismatched parameter type [parameter #%v: expected %v; got %v].", paramIndex, expectedType,actualType) 
     panic(errStr) 
    } 
} 
+0

感謝您的回答。我已經實施了您的建議更改,他們的工作很好。但是,我剛剛提出了一個有點人爲的案例,對於不能接受nil的函數,類型不兼容性檢查不會失敗。我認爲這是因爲在類型檢查完成之前,零將轉換爲兼容的零值。你看到任何優雅的解決方案嗎?相關遊樂場:http://play.golang.org/p/qvytaeewtW – Deity 2014-10-12 04:24:12

+0

啊,明白了。再次感謝! – Deity 2014-10-12 04:45:06