• Stars
    star
    70
  • Rank 447,738 (Top 9 %)
  • Language
    Go
  • License
    Other
  • Created almost 5 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A test-friendly replacement for golang's time package [managed by soy-programador]

timex

Build Status Coverage Status GoDoc

timex is a test-friendly replacement for the time package.

Usage

Just replace your time.Now() by a timex.Now() call, etc.

Mocking

Use timex.Override(...) to replace the current implementation by another one, and use the function it returns to restore the default implementation. You can't override from several tests at the same time. You can use an auto-generated by mockery mock from timexmock package, or a controlled implementation from timextest.

timexmock

There's a timexmock.Mocked(func(mocked *timexmock.Implementation) { ... }) wrapper that automatically creates a mock, sets it as the implementation to be used and defers a tear down to set the default implementation again.

Example:

func TestSleep(t *testing.T) {
	timexmock.Mocked(func(mocked *timexmock.Implementation) {
		mocked.On("Sleep", someDuration).Once()
		defer mocked.AssertExpectations(t)

		timex.Sleep(someDuration)
	})
}

timextest

Timextest provides a more complex API useful to control the behavior of concurrent programs, it is especially useful when the code interacts with timers like time.Ticker. Just like timexmock, timextest also provides a timextest.Mocked(time.Time, func(*TestImplementation)) function to make mocking easier. Few examples can be found in timextest/example_test.go, this is one of them:

func ExampleTestImplementation_NewTicker() {
	timextest.Mocked(now, func(mockedtimex *timextest.TestImplementation) {
		go func() {
			ticker := timex.NewTicker(time.Hour)
			for t := range ticker.C() {
				fmt.Printf("%s\n", t)
			}
		}()

		tickerCall := <-mockedtimex.NewTickerCalls
		tickerCall.Mock.Tick(now.Add(time.Second))
		tickerCall.Mock.Tick(now.Add(2 * time.Second))

		// Output:
		// 2009-11-10 23:00:01 +0000 UTC
		// 2009-11-10 23:00:02 +0000 UTC
	})
}

Drawbacks

Performance

There's an obvious performance impact caused by the indirection of the call, it's actually 20-30% slower, however, in absolute numbers we're talking about 30 nanoseconds per call, so you probably should not worry about that. Notice that the difference is so small that it's not easy to get a stable result.

$ go test -run=NONE -benchmem -benchtime=5s -bench=. .
goos: darwin
goarch: amd64
pkg: github.com/cabify/timex
BenchmarkTimeNow-4    	49619665	       112 ns/op	       0 B/op	       0 allocs/op
BenchmarkTimexNow-4   	41256012	       145 ns/op	       0 B/op	       0 allocs/op

If you're really worried about performance, you can disable part of the indirection by compiling with timex_disable tag, which will provide results similiar to the native implemenation calls:

$ go test -run=NONE -benchmem -benchtime=5s -bench=. -tags=timex_disable .
goos: darwin
goarch: amd64
pkg: github.com/cabify/timex
BenchmarkTimeNow-4    	49866967	       116 ns/op	       0 B/op	       0 allocs/op
BenchmarkTimexNow-4   	47965780	       109 ns/op	       0 B/op	       0 allocs/op

Dogma

Oh... yes, we're changing global variables and we'll obviously burn in hell, but if you're really into DI, you can also accept timex.Implementation interface as a dependency, and then inject either timex.Default{} or a testable implementation.

More Repositories

1

gotoprom

Type-safe Prometheus metrics builder library for golang [managed by soy-programador]
Go
109
star
2

aceptadora

Aceptadora provides the boilerplate to orchestrate the containers for an acceptance test. [managed by soy-programador]
Go
57
star
3

prom-react

Add Prometheus metrics to your React App. Built on top of promjs and react-performance libraries [managed by soy-programador]
TypeScript
27
star
4

deckset-slides-theme

A custom, on brand Cabify theme for Deckset, the app to create super nice presentations with just Markdown
17
star
5

logrusiowriter

io.Writer implementation using logrus logger [managed by soy-programador]
Go
16
star
6

figma-plugin-frametastic

Add your favorite frame sizes combinations to easily test your designs in different viewports.
HTML
8
star
7

couchdb-admin

CouchDB admin tooling
Go
7
star
8

runnerpool

Golang library providing a limited worker pool implementation [managed by soy-programador]
Go
6
star
9

better-crowdin

Crowdin CLI on steroids
JavaScript
5
star
10

foam

A SOAP 1.1 client [managed by soy-programador]
Go
5
star
11

repoman

Magefile Repository Manager Support Package.
Go
5
star
12

MobileChallenge

Mobile Challenge for Android and iOS candidates repository [managed by soy-programador]
4
star
13

frontend-shopping-cart-challenge-basic

Cabify basic shopping cart challenge
CSS
2
star
14

cabify_payments_js_encryption

JS client library for encrypting payment details before sending them to the server.
JavaScript
2
star
15

eslint-config

ESLint config for Cabify Javascript projects [managed by soy-programador]
JavaScript
2
star
16

systems-challenge

Cabify Systems Technical Challenge
Ruby
2
star
17

couchrest_model_elastic

Add Elasticsearch to your CouchRest models
Ruby
1
star
18

package-build-javascript

Package build configuration based on Rollup to compile JS packages
JavaScript
1
star
19

motion-maps-wrapper

A common API plus some helpers for the Apple and Google maps frameworks to use with RubyMotion.
Ruby
1
star
20

gofixunkeyedcomposites

Command gofixunkeyedcomposites adds keys to composite literal fields.
Go
1
star
21

ui-metropolis-challenge

Cabify UI Metropolis challenge
1
star
22

go-logging

Simple logging package for Go [managed by soy-programador]
Go
1
star