Daily Archives: 07.02.2021
Mocking for unit-tests and e2e-tests in golang
Some patterns to test your golang app. Mocking an interface
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
mockS3 := &mocks.S3API{} mockResultFn := func(input *s3.ListObjectsInput) *s3.ListObjectsOutput { output := &s3.ListObjectsOutput{} output.SetCommonPrefixes([]*s3.CommonPrefix{ &s3.CommonPrefix{ Prefix: aws.String("2017-01-01"), }, }) return output } // NB: .Return(...) must return the same signature as the method being mocked. // In this case it's (*s3.ListObjectsOutput, error). mockS3.On("ListObjects", mock.MatchedBy(func(input *s3.ListObjectsInput) bool { return input.Delimiter != nil && *input.Delimiter == "/" && input.Prefix == nil })).Return(mockResultFn, nil) listingInput := &s3.ListObjectsInput{ Bucket: aws.String("foo"), Delimiter: aws.String("/"), } listingOutput, err := mockS3.ListObjects(listingInput) if err != nil { panic(err) } for _, x := range listingOutput.CommonPrefixes { fmt.Printf("common prefix: %+v\n", *x) } |
https://github.com/vektra/mockery Mocking SQL database
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// a successful case func TestShouldUpdateStats(t *testing.T) { db, mock, err := sqlmock.New() if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() mock.ExpectBegin() mock.ExpectExec("UPDATE products").WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectExec("INSERT INTO product_viewers").WithArgs(2, 3).WillReturnResult(sqlmock.NewResult(1, 1)) mock.ExpectCommit() // now we execute our method if err = recordStats(db, 2, 3); err != nil { t.Errorf("error was not expected while updating stats: %s", err) } // we make sure that all expectations were met if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("there were unfulfilled expectations: %s", err) } } |
https://github.com/DATA-DOG/go-sqlmock Mocking HTTP server for unit-tests
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
handler := func(w http.ResponseWriter, r *http.Request) { io.WriteString(w, "<html><body>Hello World!</body></html>") } req := httptest.NewRequest("GET", "http://example.com/foo", nil) w := httptest.NewRecorder() handler(w, req) resp := w.Result() body, _ := ioutil.ReadAll(resp.Body) fmt.Println(resp.StatusCode) fmt.Println(resp.Header.Get("Content-Type")) fmt.Println(string(body)) |
https://golang.org/pkg/net/http/httptest/ Stubbing HTTP server for e2e-tests
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
{ "host": "example.com", "method": "GET|POST|PUT|PATCH|... (Mandatory)", "path": "/your/path/:variable (Mandatory)", "queryStringParameters": { "name": ["value"], "name": ["value", "value"] }, "headers": { "name": ["value"] }, "cookies": { "name": "value" }, "body": "Expected Body" } |
https://github.com/jmartin82/mmock Mocking for e2e-tests with dockertest
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
var db *sql.DB func TestMain(m *testing.M) { // uses a sensible default on windows (tcp/http) and linux/osx (socket) pool, err := dockertest.NewPool("") if err != nil { log.Fatalf("Could not connect to docker: %s", err) } // pulls an image, creates a container based on it and runs it resource, err := pool.Run("mysql", "5.7", []string{"MYSQL_ROOT_PASSWORD=secret"}) if err != nil { log.Fatalf("Could not start resource: %s", err) } // exponential backoff-retry, because the application in the container might not be ready to accept connections yet if err := pool.Retry(func() error { var err error db, err = sql.Open("mysql", fmt.Sprintf("root:secret@(localhost:%s)/mysql", resource.GetPort("3306/tcp"))) if err != nil { return err } return db.Ping() }); err != nil { log.Fatalf("Could not connect to docker: %s", err) } code := m.Run() // You can't defer this because os.Exit doesn't care for defer if err := pool.Purge(resource); err != nil { log.Fatalf("Could not purge resource: %s", err) } os.Exit(code) } func TestSomething(t *testing.T) { // db.Query() } |
https://github.com/ory/dockertest