DEV Community

Alireza Bashiri
Alireza Bashiri

Posted on

Go already has RSpec!

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)

Collapse
 
quii profile image
Chris James

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!

Collapse
 
ladydascalie profile image
Benjamin Cable

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.

Collapse
 
rhymes profile image
rhymes

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.

Collapse
 
alirezabashiri profile image
Alireza Bashiri

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.