From a7c870f8f95c06b828d9bfce03d7ba52b0733fbe Mon Sep 17 00:00:00 2001 From: mo khan Date: Thu, 19 May 2022 09:40:00 -0600 Subject: add notes on golang testing --- learn/golang/README.md | 102 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) diff --git a/learn/golang/README.md b/learn/golang/README.md index 2062a3c..ead94b6 100644 --- a/learn/golang/README.md +++ b/learn/golang/README.md @@ -140,3 +140,105 @@ type Handler interface { This means that any `type` that implements the function `ServeHTTP(w, *r)` can be used as a `Handler` for the HTTP Mux. + +## Testing + +The Go stdlib includes a [testing package](https://go.dev/doc/code#Testing). +These tests can be run using `$ go test`. To run all the tests in a project +folder run `$ go test ./...`. The `./...` is the way that go expresses the idea +of "just find all the go files and do the thing". + +To write a test you must declare a function name with a prefex of `Test` e.g. +`func TestMyThing`. This function must accept a parameter of type `testing.T`. + +```go +package x + +import "testing" + +func TestNew(t *testing.T) { + item := x.New() + // ... +} +``` + +The `testing.T` type can be used to declare nested blocks of tests to be able to +group associated tests together. + +```go +package x + +import "testing" + +func TestNew(t *testing.T) { + item := x.New() + t.Run("when creating a new x", func(t *testing.T){ + t.Run("it returns a pointer to a new instance", func(t testing.T){ + // ... + }) + }) +} +``` + +This allows you to write tests in the form of 'Context/Specifications', +'Given/When/Then', 'Arrange/Act/Assert' or however you want. + +### Assertions + +The `testing` package does not include an assertion library so the canonical way +to fail a test is to call `t.Error` or `t.Fail`. There are many different +assertion libraries out there. +[testity](https://github.com/stretchr/testify#assert-package) is a popular one. + +```go +package x + +import ( + "testing" + "github.com/stretchr/testify/assert" +) + +func TestNew(t *testing.T) { + item := x.New() + assert.NotNil(t, item) +} +``` + +### Arrange, Act, Assert + +1. Arrange: set the context for the test. +2. Act: execute some behaviour on the [subject under test](http://xunitpatterns.com/SUT.html). +3. Assert: assert that the desired result or interaction was achieved. + +```go +package calculator + +import ( + "testing" + "github.com/stretchr/testify/assert" +) + +func TestCalculator(t *testing.T) { + // arrange + calc := calculator.New() + + // act + result := cacl.Add(2, 2) + + // assert + assert.NotNil(t, 4, result) +} + +func TestCalculator(t *testing.T) { + // arrange + engine := // stub TODO:: figure out how to stub interfaces + calc := calculator.NewWithEngine(engine) + + // act + result := cacl.Add(2, 2) + + // assert + // engine.Compute("+", 2, 2) TODO:: figure out how to assert interactions on a mock or stub. + // e.g. expect(engine).to have_received(:compute).with("+", 2, 2) +} +``` -- cgit v1.2.3