2016-03-18 3 views
2

В моем тестовом файле я пытаюсь сравнить фактическую ошибку, обнаруженную с ожидаемой ошибкой. Однако это сравнение оценивается как ложное, и я не уверен, почему. Это происходит даже тогда, когда я создаю две идентичные ошибки и сравниваю их.Сравнение ошибок в Go

Фрагмент кода:

func TestCompareErrors(t *testing.T) { 
    if fmt.Errorf("Test Error") != fmt.Errorf("Test Error") { 
     t.Errorf("Test failed") 
    } 
} 

Это приводит к «Тест не удалось»

ответ

3

Вы сравниваете два различных значения, которые происходят, чтобы иметь то же самое сообщение об ошибке. Вы хотите сравнить предопределенные значения ошибок, как и с обычными значениями, например io.EOF.

http://play.golang.org/p/II8ZeASwir

var errTest = fmt.Errorf("test error") 

func do() error { 
    return errTest 
} 

func main() { 
    err := do() 
    if err == errTest { 
     log.Fatal("received error: ", err) 
    } 

} 

Вы можете прочитать "Errors are Values" для более подробного описания работы.

Если вам нужна дополнительная информация об ошибке, вы можете создать свой собственный тип ошибки. Затем вы можете присоединить любую информацию, которую хотите к ошибке, и проверить этот тип ошибки с помощью утверждения типа.

type myError string 

func (e myError) Error() string { 
    return string(e) 
} 

func do() error { 
    return myError("oops") 
} 

func main() { 
    err := do() 
    if err, ok := err.(myError); ok { 
     log.Fatal("received myError: ", err) 
    } 
} 
+2

Хорошо, но что, если сообщение в вашей ошибки имеет динамическое содержимое (например, «Неожиданный вход: [что-то]» или в том, что плохая практика в данном случае – edwardmp

+1

@edwardmp: да, наличие динамического сообщения в ошибке, как правило, плохое, поскольку вы теряете способность сравнивать значения. Вы можете использовать такие методы, как ['net.OptError'] (https://golang.org/pkg/net/#OpError) (который удовлетворяет ['net.Error'] (https://golang.org/pkg/net/#Error) и' error'), где вы прикрепляете дополнительную информацию к ошибке, и вы проверяете тип ошибки с помощью тип утверждения и его методы. – JimB

+0

Правильно, это хорошее решение. – edwardmp

3

Используйте reflect.DeepEqual для сравнения значений.

if reflect.DeepEqual(fmt.Errorf("Test Error"), fmt.Errorf("Test Error")) { 
    // the error values are same. 
} 

Пример в playground

Смежные вопросы