Skip to content

Testing Tools and ksql.Mock

Vinícius Garcia edited this page Jul 4, 2022 · 1 revision

ksql.Mock is a simple mock that is available out of the box for the ksql.Provider interface.

For each of the methods available on the interface, this Mock has a function attribute with the same function signature and with the same name but with an Fn at the end of the name.

For instantiating this mock and at the same time mocking one of the functions all you need to do is this:

var capturedRecord interface{}
var capturedQuery string
var capturedParams []interface{}
mockDB := ksql.Mock{
  QueryOneFn: func(ctx context.Context, record interface{}, query string, params ...interface{}) error {
    capturedRecord = record
    capturedQuery = query
    capturedParams = params

    // For simulating an error you would do this:
    return fmt.Errorf("some fake error")
  },
}

var user User
err := GetUser(db, &user, otherArgs)
assert.NotNil(t, err)
assert.Equal(t, user, capturedRecord)
assert.Equal(t, `SELECT * FROM user WHERE other_args=$1`, capturedQuery)
assert.Equal(t, []interface{}{otherArgs}, capturedParams)

For different types of functions, you might need to do some tricks with structs to make it easier to write the tests such as:

Converting a struct to something that is easier to assert like a map[string]interface{} or filling a struct with fake data from the database, for these situations the library provides the following helper functions:

  • ksqltest.FillStructWith(struct interface{}, dbRow map[string]interface{}) error
  • ksqltest.FillSliceWith(structSlice interface{}, dbRows []map[string]interface{}) error
  • ksqltest.StructToMap(struct interface{}) (map[string]interface{}, error)

For example:

createdAt := time.Now().Add(10*time.Hour)
mockDB := ksql.Mock{
  QueryOneFn: func(ctx context.Context, record interface{}, query string, params ...interface{}) error {
    // For simulating a succesful scenario you can just fillup the struct:
    return ksqltest.FillStructWith(record, map[string]interface{}{
      "id": 42,
      "name": "fake-name",
      "age": 32,
      "created_at": createdAt,
    })
  },
}

var user User
err := GetUser(db, &user, otherArgs)
assert.Nil(t, err)
assert.Equal(t, user, User{
  ID: 42,
  Name: "fake-name",
  Age: 32,
  CreatedAt: createdAt,
})

And for running tests on the QueryChunks function which is a particularly complex function we also have this test helper:

  • ksqltest.CallFunctionWithRows(fn interface{}, rows []map[string]interface{}) (map[string]interface{}, error)

If you want to see examples (we have examples for all the public functions) just read the example tests available on our example service.

Please note that in the example service above we have two sets of tests in two different files, exemplifying how to use gomock and then how to use ksql.Mock{}.