Stubbing time.Now() during tests golang?

7.3k Views Asked by At

I'm following another answer here: Is there an easy way to stub out time.Now() globally during test?

So I have this file where I do something like:

var timeNow = time.Now

func GenerateTimestamp() int64 {
    now := timeNow() // current local time
    sec := now.Unix() // number of seconds since January 1, 1970 UTC

    return sec // int 64
}

We use GenerateTimestamp() in another function

func AddTs() {
    // Some if check, use GenerateTimestamp() here
}

Now on my test file, I am doing something like:

    now := time.Now()
    timeNow = func() int64 {
        // fmt.Println("looking for this", now.Unix())
        return now.Unix()
    }

I am getting this error cannot use func literal (type func() int64) as type func() time.Time in assignment. I need to be able to return an int64 type (which my original function returns), how can I get around this?

Feel free to point me to docs, I am a Go newbie!!

1

There are 1 best solutions below

1
On BEST ANSWER

time.Now() is a function that returns a value of type time.Time:

func Now() Time

So the type of timeNow is a function of this type: func() time.Time. This is obviously different than func() int64.

You have to return a time.Time value. If you want to return a time.Time value that represents a specific unix time, you may use the time.Unix() function to get that value, e.g.

unixsec := int64(1605139200) // This is 2020-11-12 00:00:00 +0000 UTC

timeNow = func() time.Time {
    return time.Unix(unixsec, 0)
}

If you want to return a specific date-time, you may use time.Date(), e.g.:

timeNow = func() time.Time {
    return time.Date(2020, 11, 12, 0, 0, 0, 0, time.UTC)
}

Of course you are not limited to always return the same time instant. You can return incrementing time values on each call, e.g.:

unixsec := int64(1605139200) // This is 2020-11-12 00:00:00 +0000 UTC

timeNow = func() time.Time {
    unixsec++ // Increment number of seconds by 1
    return time.Unix(unixsec, 0)
}

This timeNow function will return a time value that is always incremented by 1 second (compared to the value returned by the previous call).