How to make a nullable field in a struct
Asked Answered
S

4

38

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?

Succinctorium answered 24/8, 2018 at 5:47 Comment(5)
Is SomeType a struct or interface. Please post more code information.Isopropanol
Sorry, it is struct.Succinctorium
Sorry SomeType is User, and it is struct. I edited my questionSuccinctorium
Then if it's a structure - make it a pointer.Dietetics
@Succinctorium why do you think you cannot make expected a pointer?Viridi
I
28

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
}
Isopropanol answered 24/8, 2018 at 6:4 Comment(0)
T
19

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

Trinitrocresol answered 24/8, 2018 at 7:6 Comment(2)
Is there any standard for this, or at least official go draft, or issue opened? It's quite missing feature, there are many cases, where there's need to differentiate between missing value and zero value. E.g. examResults.Score == 0 (no points), and examResults.Score == nil (unknown score).Eparchy
You can use the null types included in the standard library in the sql package like sql.NullBool and sql.NullInt32. pkg.go.dev/database/sqlUniaxial
F
14

You can also use special sql type:

type structName struct {
    id sql.NullInt64
    name sql.NullString
    field sql.NullBool
}
Frivolity answered 28/5, 2020 at 19:1 Comment(0)
E
3

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

testCases := []struct {
    name          string
    testUserID    uint
    expected      any
    expectedError error
}
Encyclopedist answered 26/4, 2022 at 3:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.