Don’t Let time.Now() Breaks Your Unit Test

Ray Lin
2 min readNov 13, 2022

When people want to get the current time in the Go, the first thing that comes up must be the time.Now(). I will give you an example of what you should notice when you get the current time in the codes.

source code

The Original Design

For example, here’s a message service with a method called Send. The Send method accept two arguments, title and content. When sending the message, it will record send time when before sends the message.

Of course you’ll write a test to make sure that the Send method works fine. The main goal of test is to check the sent out title and content is equal to the given values. More importantly, the send time should be equal to the expected time of sending the message.

Oops! The test failed. The result output shows that the sending time is not same as the expcted time. The actual value just a slightly different to the expected value with milliseconds.

The failed reason is the unit test has no control of the time.Now() insides the Send method. The expected value of time.Now() is different to the time.Now() inside Send.

The Better Design

A easy solution to solve this problem is to create a Now() in the MessageService struct so that you can manipulate the time.Now() outside the MessageService struct.

Just make a Now() function when initializing the MessageService in the unit test. This will make sure the Now() will return a fixed time when the MessageService call itself Now() function.

With a small change, the time consistency problem solved. If you have different approach, welcome to comment below to share.

--

--