Хотя я знаю, что может быть идиоматично паниковать в Go, я бы хотел протестировать, чтобы обеспечить функцию паники при определенных условиях, а не в других.Проверка совместимых типов с использованием отражения в Go
Пример функции.
func PanicOnErr(potentialErr error) {
if potentialErr != nil {
panic(potentialErr)
}
}
Ниже приведена реализация для проверки того, будет ли функция паниковать.
func InvocationCausedPanic(f interface{}, params ...interface{}) bool {
// Obtain the function's signature.
reflectedFunc := reflect.ValueOf(f)
funcType := reflect.TypeOf(f)
if funcType.NumIn() != len(params) {
panic("InvocationCausedPanic called with a function and an incorrect number of parameter(s).")
}
reflectedParams := make([]reflect.Value, len(params))
for paramIndex, paramValue := range params {
expectedType := funcType.In(paramIndex)
actualType := reflect.TypeOf(paramValue)
if actualType != expectedType {
errStr := fmt.Sprintf("InvocationCausedPanic called with a mismatched parameter type [parameter #%v: expected %v; got %v].", paramIndex, expectedType, actualType)
panic(errStr)
}
reflectedParams[paramIndex] = reflect.ValueOf(paramValue)
}
return invoke(reflectedFunc, reflectedParams)
}
func invoke(reflectedFunc reflect.Value, reflectedParams []reflect.Value) (panicked bool) {
defer func() {
if r := recover(); r != nil {
panicked = true
}
}()
reflectedFunc.Call(reflectedParams)
return
}
Вызов любого из следующих способов приведет к сбою проверки типа.
InvocationCausedPanic(PanicOnErr, errors.New("Some error."))
InvocationCausedPanic(PanicOnErr, nil)
Тем не менее, кажется, можно назвать PanicOnErr
использованием как nil
и что-то произвести, вызвав errors.New
(кажется, типа *errors.errorString
).
Таким образом, существует ли способ проверить, подходит ли тип некоторого параметра для вызова некоторой функции?
Хотя я знаю, что можно использовать отсрочку и восстановление для более простого тестирования функции, мне любопытно, можно ли написать общую функцию, которая может принимать любые функции и параметры и определять, привело ли это к паника (при условии, что функция завершена).
Соответствующая Go площадка: http://play.golang.org/p/qUG7OGuIbD
Спасибо. Это решило проблему совместимости типов! – Deity
Еще раз спасибо за помощь. Я задал следующий вопрос; возможно, вы тоже знаете ответ на этот вопрос. http://stackoverflow.com/questions/26321115 – Deity