'How to make a nullable field in a struct

I'm struggling to do table driven test, and I want do this:

testCases := []struct {
    name          string
    testUserID    uint
    expected      User // <- maybe nil
    expectedError error
}

Because the return values of tested function is *User, error.

User is like this, it is defined as DB scheme.

type User struct {
  ID uint
  CreatedAt time.Time
  UpdatedAt time.Time
  ...
}

But in this case, I cannot make expected nil.

How can I do this?

Or my approach to do table driven test is wrong?



Solution 1:[1]

For empty field you can check for empty values which is zero value which is not nil in case of struct.

When storage is allocated for a variable, either through a declaration or a call of new, or when a new value is created, either through a composite literal or a call of make, and no explicit initialization is provided, the variable or value is given a default value. Each element of such a variable or value is set to the zero value for its type: false for booleans, 0 for numeric types, "" for strings, and nil for pointers, functions, interfaces, slices, channels, and maps.

In your case are using the Struct not a pointer to struct. The value is not nil it is empty though

var user User
fmt.Println(user == User{}) // will print true

But since in your case the returned value is pointer to struct *User, error you can check for nil

var user *User
fmt.Println(user == nil) // will print true

Create struct field that is a pointer.

testCases := []struct {
    name          string
    testUserID    uint
    expected      *User // <- maybe nil
    expectedError error
}

Solution 2:[2]

Go basic types have defined zero values and cannot be nil.

If you want a value to be simply nillable, make it a pointer.

If you do not want a pointer behaviour, you can use null types from third party packages,

e.g. https://github.com/guregu/null

for example int is implemented as:

type Int struct {
    Int   int
    Valid bool
}

another solution is to write your own struct with nullable value

Solution 3:[3]

You can also use special sql type:

type structName struct {
    id sql.NullInt64
    name sql.NullString
    field sql.NullBool
}

Solution 4:[4]

also you can use any, and will accept any value.

testCases := []struct {
    name          string
    testUserID    uint
    expected      any
    expectedError error
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Flimzy
Solution 2 Krzysztof Skolimowski
Solution 3 Egor Matveev
Solution 4 Fernando Aguirre