Em Ae
Em Ae

Reputation: 8724

How test if defer is called or not

I have following code

func (s *MyRepo) InsertOrder(ctx context.Context, orderID string) error {
    query := `INSERT INTO orders (orderID) VALUES (?)`

    stmt, err := s.db.RawDatabase().PrepareContext(ctx, query)
    if err != nil {
        return err
    }
    defer stmt.Close()

    _, err = stmt.ExecContext(ctx, orderID)
    if err != nil {
        //log err
    }
    return err
}

And the corresponding test case is

func TestMyRepo_InsertOrder_Success(t *testing.T) {
    orderID := "orderID"
    mockDB, repo := getDBStore()
    query := `[INSERT INTO orders (orderID) VALUES (?)]`
    mockDB.ExpectPrepare(query).
        ExpectExec().
        WithArgs(orderID).
        WillReturnResult(sqlmock.NewResult(1, 1)).
        WillReturnError(nil)

    err := repo.InsertOrder(context.Background(), orderID)
    assert.Nil(t, err)
}

But this doesn't test if defer stmt.Close() has been called or not (which gets called once the function ends). How can I test this?

Upvotes: -5

Views: 1839

Answers (1)

Jesse Amano
Jesse Amano

Reputation: 828

It looks like you are making use of data-dog's sqlmock package, so you ought to be able to use ExpectClose() to register the expectation that the database will be closed, and ExpectationsWereMet() to collect this information.

If you're using some other package, feel free to link it; there's probably something similar available, and worst-case you can write your own wrapper around their wrapper. Making sure that a particular method of a particular dependency was called is a fairly common desire when developers write tests using mocks, so most of the better mock packages will go out of their way to provide some sort of API to check that.

As noted in the comments on this question, tests of this nature are often of somewhat questionable value and can seem like they exist more to increase a dubious metric like % code coverage than to increase code reliability or maintainability.

Upvotes: 1

Related Questions