Это мой первый пост на dev.to , X-опубликовано в моем новом личном блоге которые можно найти здесь . Надеюсь, у меня будет dev.to публикация из RSS кормит, как только я с этим разберусь!
Будем рады получить любую обратную связь, которая у вас может возникнуть! 😃
Мне нравится подтверждать стабильность моего кода с помощью написания тестов и практики разработки на основе тестирования (TDD). Для Java JUnit был моим предпочтительным фреймворком тестирования. При написании тестов для подтверждения возникновения исключения я использовал необязательный параметр expected для аннотации @Test , однако я быстро обнаружил, что это решение не будет работать для методов, в которых я несколько раз вызывал один и тот же класс исключений для разных сообщений об ошибках, и тестирование на эти сообщения.
Это обычно встречается при написании метода проверки, такого как приведенный ниже, который принимает имя собаки и возвращает логическое значение, если оно допустимо.
public static boolean validateDogName(String dogName) throws DogValidationException {
if (containsSymbols(dogName)) {
throw new DogValidationException("Dogs cannot have symbols in their name!");
}
if (dogName.length > 100) {
throw new DogValidationException("Who has a name for a dog that long?!");
}
return true;
}
Для этого метода просто используйте @Test(expected.class )
Чтобы решить эту проблему, я наткнулся на класс ExpectedException для JUnit в Baeldung , который позволяет нам указать ожидаемое сообщение об ошибке. Здесь он применяется к тестовому варианту для этого метода:
@Rule
public ExpectedException exceptionRule = ExpectedException.none();
@Test
public void shouldHandleDogNameWithSymbols() {
exceptionRule.expect(DogValidationException.class);
exceptionRule.expectMessage("Dogs cannot have symbols in their name!");
validateDogName("GoodestBoy#1");
}
Возвращаясь к Golang, отметим, что существует встроенная библиотека с метким названием testing , которая позволяет нам утверждать условия тестирования. В сочетании с Go tests – инструментом для создания Go-тестов из вашего кода – написание тестов не может быть проще! Мне нравится, как это сочетается с расширением Go для VS Code, моим любимым текстовым редактором (на данный момент …).
Преобразование вышеупомянутого Java validatetagname метод для Golang выдаст что-то вроде:
func validateDogName(name string) (bool, error) {
if containsSymbols(name) {
return false, errors.New("dog cannot have symbols in their name")
}
if len(name) > 100 {
return false, errors.New("who has a name for a dog that long")
}
return true, nil
}
Если у вас есть метод Go, который возвращает интерфейс error , то go tests сгенерирует тест, который будет выглядеть следующим образом:
func Test_validateDogName(t *testing.T) {
type args struct {
name string
}
tests := []struct {
name string
args args
want bool
wantErr bool
}{
name: "Test error was thrown for dog name with symbols",
args: args{
name: "GoodestBoy#1",
},
want: false,
wantErr: true,
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := validateDogName(tt.args.name)
if (err != nil) != tt.wantErr {
t.Errorf("validateDogName() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("validateDogName() = %v, want %v", got, tt.want)
}
})
}
}
Исходя из вышесказанного, мы ограничены тем, какую ошибку мы можем утверждать, здесь любая возвращенная ошибка пройдет проверку. Это эквивалентно использованию @Test(expected=Exception.class ) в JUnit! Но есть и другой способ…
Изменение сгенерированного теста
Нам нужно всего лишь внести несколько простых изменений в сгенерированный тест, чтобы дать нам возможность утверждать в сообщении об ошибке теста…
func Test_validateDogName(t *testing.T) {
type args struct {
name string
}
tests := []struct {
name string
args args
want bool
wantErr error
}{
name: "Test error was thrown for dog name with symbols",
args: args{
name: "GoodestBoy#1",
},
want: false,
wantErr: errors.New("dog cannot have symbols in their name"),
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := validateDogName(tt.args.name)
if tt.wantErr != nil && !reflect.DeepEqual(err, tt.wantErr) {
t.Errorf("validateDogName() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("validateDogName() = %v, want %v", got, tt.want)
}
})
}
}
Из вышесказанного есть три изменения, давайте рассмотрим их по отдельности:
хочу ошибиться ошибка- мы меняем это с
boolчтобы мы могли провести сравнение с ошибкой, возвращаемой функцией
- мы меняем это с
wantErr: ошибки. Новое ("у собаки не может быть символов в имени"),- это структура ошибки, которая мы ожидаем
если tt.wantErr && !отразит. deepEqual(ошибка, т.е.wantErr) {- проверьте, чтобы убедиться, что в тесте ожидается ошибка, если это так, то сравните ее с возвращенной ошибкой
Пункт 3 обеспечивает дополнительную поддержку, если был тестовый пример, который не ожидал ошибки. Обратите внимание, что water полностью исключен из приведенного ниже тестового примера.
{
name: "Should return true for valid dog name",
args: args{
name: "Benedict Cumberland the Sausage Dog",
},
want: true,
}
Настройка тестов Сгенерированный тест
Go tests дает нам возможность предоставлять наши собственные шаблоны для создания тестов и может быть легко интегрирован в выбранный вами текстовый редактор. Я покажу вам, как это можно сделать в VSCode.
Ознакомьтесь с go tests и скопируйте каталог шаблонов в выбранное вами место
клон git https://github.com/cweill/gotests.gitcp -R gotests/internal/render/templates ~/scratch/go тесты
Перепишите содержимое function.tmpl с помощью содержимого этого Gist
Добавьте следующий параметр в настройки VSCode.json
""go.generateTestsFlags": ["--template_dir=~/scratch/templates"]
Как только вы это сделаете, будущие тесты теперь будут генерироваться с более строгим тестированием на ошибки! 🎉
Я понимаю, что приведенные выше рекомендации сделают ваш код более хрупким, поскольку код подвержен любому изменению сообщения об ошибке, скажем, нижестоящей библиотеки. Однако для себя я предпочитаю писать тесты, которые являются строгими и минимизируют вероятность других ошибок, загрязняющих тесты.
Я также понимаю, что GoodestBoy # 1, вероятно, является подходящим именем для собаки! 🐶
Оригинал: “https://dev.to/jdheyburn/extending-gotests-for-strict-error-tests-4j96”