Reputation: 9653
I've just started using Go. I'm writing unit tests and I'd like to be able to test using a table, where the result to be compared to the actual result sometimes should or should not be equal.
For example, this is the code that I currently have:
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)
}
}
}
Now, this isn't too bad, but it would be even better if the last bit could be changed to something cleaner like this for better readability:
for _, table := range tables {
actualResult := sampleFunc(table.input)
assert.EqualOrNotEqual(t, table.comparisonResult, actualResult, table.shouldBeEqual)
}
So, the first test should pass if table.comparisonResult
and actualResult
are equal, and the second test should pass if the two aren't equal.
I've looked through the testify/assert
docs and I don't think I found a function that is similar to the fake EqualOrNotEqual
function that I made up above, but perhaps I accidentally skipped over something, or there is some kind of Go special syntax that I don't know about that might help me achieve this.
Note: I am well aware that I can write my own function for this. My reason for asking was because if this is a well-established pattern, then packages/libraries often include it as a built-in function which may at times be undocumented/buried in the documentation. And if not, maybe there's a reason why I shouldn't do this, or maybe there's a better way of doing it. Starting to use a new language is very labour-intensive at first, not least because you have to learn all the new idioms and quirks and The Right Way to do things.
Upvotes: 2
Views: 7510
Reputation: 12409
Golang does have a functional aspect, although it's more rigid than in Python or JavaScript.
You can allow your struct table to hold functions if you know their signatures. Then you get rid of the if
logic inside the tests:
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)
}
}
Upvotes: 0
Reputation: 4469
Since it's just for readability, and since it appears that this function does not exist, you could just copy-paste your working code into a separate function:
func equalOrNotEqual(t TestingT, expected, actual interface{}, shouldBeEqual bool) {
if shouldBeEqual {
assert.Equal(t, expected, actual)
} else {
assert.NotEqual(t, expected, actual)
}
}
and:
for _, table := range tables {
actualResult := sampleFunc(table.input)
equalOrNotEqual(t, table.comparisonResult, actualResult, table.shouldBeEqual)
}
Upvotes: 2