Можно ли динамически утверждать, что два значения равны или не равны при модульном тестировании в Go?
Я только начал использовать Go. Я пишу модульные тесты, и я хотел бы иметь возможность тестировать, используя таблицу, где результат, который нужно сравнить с фактическим результатом, иногда должен быть или не быть равным.
Например, это код, который у меня сейчас есть:
package main
import (
"github.com/stretchr/testify/assert"
"testing"
)
func TestFunc(t *testing.T) {
tables := []struct {
input string
comparisonResult string
shouldBeEqual bool
}{
{
"some irrelevant input",
"some result",
true,
},
{
"some other irrelevant input",
"some other result",
false,
},
}
for _, table := range tables {
actualResult := sampleFunc(table.input)
if table.shouldBeEqual {
assert.Equal(t, table.expectedResult, actualResult)
} else {
assert.NotEqual(t, table.expectedResult, actualResult)
}
}
}
Теперь, это не так уж плохо, но было бы еще лучше, если бы последний бит мог быть изменен на что-то более чистое, например, для лучшей читаемости:
for _, table := range tables {
actualResult := sampleFunc(table.input)
assert.EqualOrNotEqual(t, table.comparisonResult, actualResult, table.shouldBeEqual)
}
Итак, первый тест должен пройти, если table.comparisonResult
а также actualResult
равны, и второй тест должен пройти, если два не равны.
Я посмотрел через testify/assert
документы, и я не думаю, что я нашел функцию, которая похожа на подделку EqualOrNotEqual
функции, которую я составил выше, но, возможно, я случайно пропустил что-то, или есть какой-то специальный синтаксис Go, о котором я не знаю, который мог бы помочь мне достичь этого.
Примечание: я хорошо знаю, что могу написать свою собственную функцию для этого. Моя причина была в том, что если это хорошо установленный шаблон, то пакеты / библиотеки часто включают его в качестве встроенной функции, которая иногда может быть недокументирована / похоронена в документации. А если нет, возможно, есть причина, почему я не должен этого делать, или, может быть, есть лучший способ сделать это. Начать использовать новый язык поначалу очень трудоемко, не в последнюю очередь потому, что вам нужно выучить все новые идиомы и причуды, а также "Правильный путь".
2 ответа
Так как это просто для удобства чтения, и поскольку кажется, что эта функция не существует, вы можете просто скопировать и вставить свой рабочий код в отдельную функцию:
func equalOrNotEqual(t TestingT, expected, actual interface{}, shouldBeEqual bool) {
if shouldBeEqual {
assert.Equal(t, expected, actual)
} else {
assert.NotEqual(t, expected, actual)
}
}
а также:
for _, table := range tables {
actualResult := sampleFunc(table.input)
equalOrNotEqual(t, table.comparisonResult, actualResult, table.shouldBeEqual)
}
У Голанга есть функциональный аспект, хотя он более жесткий, чем в Python или JavaScript.
Вы можете разрешить вашей структуре таблицы содержать функции, если вы знаете их подписи. Тогда вы избавитесь от if
логика внутри тестов:
func TestFunc(t *testing.T) {
tables := []struct {
input string
comparisonResult string
assert func(assert.TestingT, interface{}, interface{}, ...interface{}) bool
}{
{
input: "some irrelevant input",
comparisonResult: "some result",
assert: assert.Equal,
},
{
input: "some other irrelevant input",
comparisonResult: "some other result",
assert: assert.NotEqual,
},
}
for _, table := range tables {
actualResult := sampleFunc(table.input)
table.assert(t, table.comparisonResult, actualResult)
}
}