You can use (*testing.T).Run(string, func(t *testing.T))
to run each test case in isolation and also is more readable than table driven approach.
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestRateRecipe(t *testing.T) {
t.Run("ok", func(t *testing.T) {
res := post("/recipes/1/rating", nil)
assert.Equal(t, res.Code, http.StatusOK)
})
t.Run("id is invalid", func(t *testing.T) {
res := post("/recipes/foo/rating", nil)
assert.Equal(t, res.Code, http.StatusBadRequest)
})
}
Top comments (4)
I dont think
t.Run
and table tests are mutually exclusive. Also table tests dont have to be hard to read :)But table tests are sometimes reached out to when maybe they're not neccessary.
Overall though, i agree that you really dont have to use frameworks to write tests in Go, that's why it's so great!
Correct, they are not mutually exclusive. I often end up using both, sometimes one pattern fits better.
Table-driven tests are really good if your tests would otherwise involve a lot of boilerplate to be repeated over and over. But in some other cases, simply isolating is good enough.
I'm conflicted on the table driven approach as well. But I think that for testing "error cases" is the best. You just list them all and done. Also it saves a lot of code duplication.
I tend not to use the test tables for the "ok" response, so that I can dig into the response and check everything's how it's supposed to be.
I think there's a conflict in Go community too when it comes to writing a program, duplication becomes a second-citizen but in testing duplication not tolerated.