如何测试是否调用延期

时间:2019-06-14 19:30:27

标签: unit-testing go mocking deferred

我有以下代码

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
}

对应的测试用例是

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)
}

但这不能测试是否已调用defer stmt.Close()(函数结束后即被调用)。我该如何测试?

1 个答案:

答案 0 :(得分:1)

您似乎正在使用data-dog的sqlmock包,因此您应该能够使用ExpectClose()来注册数据库将关闭的期望,以及{{1} }收集这些信息。

如果您正在使用其他软件包,请随时进行链接;可能有类似的可用方法,最坏的情况是您可以在其包装器周围编写自己的包装器。当开发人员使用模拟编写测试时,确保调用具有特定依赖关系的特定方法是一种很普遍的愿望,因此,大多数更好的模拟包都会竭尽所能提供某种API进行检查。

正如对此问题的评论中所指出的那样,这种性质的测试通常具有可疑的价值,并且看起来它们存在的可能性更多是为了增加诸如代码覆盖率之类的可疑指标,而不是增加代码的可靠性或可维护性。