From 28dbc1ab98670af0747dc2a23cd8687715f469d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernd-Ren=C3=A9=20Predota?= Date: Tue, 18 May 2021 14:23:45 +0200 Subject: [PATCH] unittests further improved --- README.md | 2 +- lib/cache/cache.go | 3 +- lib/cache/cache_test.go | 55 +++++++++++++++++++++++++++++++++ lib/common/guid.go | 5 +-- lib/database/database_test.go | 57 +++++++++++++++++++++++++++++++++++ lib/response/response_test.go | 43 ++++++++++++++++++++++++++ 6 files changed, 161 insertions(+), 4 deletions(-) create mode 100644 lib/cache/cache_test.go create mode 100644 lib/database/database_test.go create mode 100644 lib/response/response_test.go diff --git a/README.md b/README.md index 1ea291a..9e55ca6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # golang API Skeleton -[![Build Status](https://drone.devices.local/api/badges/mawas/golang-api-skeleton/status.svg)](https://drone.devices.local/mawas/golang-api-skeleton)![gopherbadger-tag-do-not-edit](https://img.shields.io/badge/Go%20Coverage-75%25-brightgreen.svg?longCache=true&style=flat) +[![Build Status](https://drone.devices.local/api/badges/mawas/golang-api-skeleton/status.svg)](https://drone.devices.local/mawas/golang-api-skeleton)![gopherbadger-tag-do-not-edit](https://img.shields.io/badge/Go%20Coverage-77%25-brightgreen.svg?longCache=true&style=flat) refined skeleton future apis should be based on diff --git a/lib/cache/cache.go b/lib/cache/cache.go index c5932bd..b361f5e 100644 --- a/lib/cache/cache.go +++ b/lib/cache/cache.go @@ -44,6 +44,7 @@ func (cache bCache) Get(key string) (*string, error) { if err := cache.db.View(func(txn *badger.Txn) error { item, err := txn.Get([]byte(key)) if err != nil { + fmt.Println(err.Error()) if err.Error() != "Key not found" { return nil } @@ -70,7 +71,7 @@ func (cache bCache) Get(key string) (*string, error) { return nil, nil } -// SetWithTTL sets a cache entry +// Set sets a cache entry func (cache bCache) Set(key string, value string) error { if err := cache.db.Update(func(txn *badger.Txn) error { err := txn.Set([]byte(key), []byte(value)) diff --git a/lib/cache/cache_test.go b/lib/cache/cache_test.go new file mode 100644 index 0000000..bc81773 --- /dev/null +++ b/lib/cache/cache_test.go @@ -0,0 +1,55 @@ +package cache + +import ( + "testing" + "time" +) + +func TestCache(t *testing.T) { + appCache, err := Bootstrap() + if err != nil { + t.Errorf("bootstrap cache failed: %v\n", err) + } + if err := appCache.Set("key", "value"); err != nil { + t.Errorf("set cache failed: %v\n", err) + } + // real result + value, err := appCache.Get("key") + if err != nil { + t.Errorf("get cache failed: %v\n", err) + } + if value == nil { + t.Error("get cache didn't fetch a value for set key") + } else if *value != "value" { + t.Errorf("get cache value should be \"value\" but is \"%s\"", *value) + } + // nil result + value, err = appCache.Get("notExisting") + if err != nil { + t.Errorf("get cache failed: %v\n", err) + } + if value != nil { + t.Error("get cache must return nil for non existing key") + } + if err := appCache.SetWithTTL("ttl", "10", 3); err != nil { + t.Errorf("set cache failed: %v\n", err) + } + value, err = appCache.Get("ttl") + if err != nil { + t.Errorf("get cache failed: %v\n", err) + } + if value == nil { + t.Error("get cache didn't fetch a value for set key") + } else if *value != "10" { + t.Errorf("get cache value should be \"10\" but is \"%s\"", *value) + } + time.Sleep(3 * time.Second) + value, err = appCache.Get("ttl") + if err != nil { + t.Errorf("get cache failed: %v\n", err) + } + if value != nil { + t.Error("get cache must return nil for expired key") + } + appCache.Close() +} diff --git a/lib/common/guid.go b/lib/common/guid.go index e1e8286..4a8e039 100644 --- a/lib/common/guid.go +++ b/lib/common/guid.go @@ -10,6 +10,7 @@ import ( // GUID our new ULID based datatype type GUID ulid.ULID +// NewGUID returns a new ulid func NewGUID() (GUID, error) { id, err := ulid.New(ulid.Now(), rand.Reader) return GUID(id), err @@ -17,7 +18,7 @@ func NewGUID() (GUID, error) { // StringToGUID -> parse string to ULID GUID func StringToGUID(s string) (GUID, error) { - id, err := ulid.Parse(s) // maybe ParseStrict + id, err := ulid.Parse(s) return GUID(id), err } @@ -37,7 +38,7 @@ func (guid GUID) MarshalJSON() ([]byte, error) { } func (guid *GUID) UnmarshalJSON(data []byte) error { - id, err := ulid.Parse(string(data)) // maybe ParseStrict + id, err := ulid.Parse(string(data)) *guid = GUID(id) return err } diff --git a/lib/database/database_test.go b/lib/database/database_test.go new file mode 100644 index 0000000..6267867 --- /dev/null +++ b/lib/database/database_test.go @@ -0,0 +1,57 @@ +package database + +import ( + "strings" + "testing" +) + +// FIXME make real unit tests +func TestConnect(t *testing.T) { + if _, err := Connect(Credentials{ + Host: "127.0.0.1", + Port: 3308, + Dialect: "mySQL", + User: "unittest", + Password: "secret", + Database: "unittest", + }); err != nil { + if !strings.HasSuffix(err.Error(), "connect: connection refused") { + t.Error(err) + } + } + if _, err := Connect(Credentials{ + Socket: "/tmp/unittest.socket", + Dialect: "mySQL", + User: "unittest", + Password: "secret", + Database: "unittest", + }); err != nil { + if !strings.HasSuffix(err.Error(), "no such file or directory") { + t.Error(err) + } + } + if _, err := Connect(Credentials{ + Host: "127.0.0.1", + Port: 3309, + Dialect: "msSQL", + User: "unittest", + Password: "secret", + Database: "unittest", + }); err != nil { + if !strings.HasSuffix(err.Error(), "connect: connection refused") { + t.Error(err) + } + } + if _, err := Connect(Credentials{ + Host: "127.0.0.1", + Port: 3310, + Dialect: "PostGRES", + User: "unittest", + Password: "secret", + Database: "unittest", + }); err != nil { + if !strings.HasSuffix(err.Error(), "connect: connection refused)") { + t.Error(err) + } + } +} diff --git a/lib/response/response_test.go b/lib/response/response_test.go new file mode 100644 index 0000000..865bd71 --- /dev/null +++ b/lib/response/response_test.go @@ -0,0 +1,43 @@ +package response + +import ( + "errors" + "testing" +) + +func TestAppendError(t *testing.T) { + const errMsg = "expected error" + envelope := Envelope{} + e := envelope.AppendError(errors.New(errMsg)) + if e.Success { + t.Error("error response Success must be false") + } + if e.Result != nil { + t.Error("error response Result must be nil") + } + if len(e.Errors) != 1 { + t.Error("error response Errors must be set") + } else if e.Errors[0] != errMsg { + t.Errorf("error response error message must be \"%s\" but is \"%s\"", errMsg, e.Errors[0]) + } +} + +func TestSetSuccess(t *testing.T) { + const result = "expected result" + envelope := Envelope{} + e := envelope.SetSuccess(result) + if !e.Success { + t.Error("success response Success must be true") + } + if e.Result == nil { + t.Error("success response Result must be set") + } + if msg, ok := e.Result.(string); ok { + if msg != result { + t.Errorf("success response result must be \"%s\" but is \"%s\"", result, msg) + } + } + if len(e.Errors) > 0 { + t.Error("success response Errors must be empty") + } +}