These steps cover writing and running your application:
- From your Terminal or console application, create a new directory called ~/projects/go-programming-cookbook/chapter9/bdd, and navigate to this directory.
- Run the following command:
$ go mod init github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter9/bdd
You should see a file called go.mod that contains the following:
module github.com/PacktPublishing/Go-Programming-Cookbook-Second-Edition/chapter9/bdd
- Create a file called handler.go with the following content:
package bdd
import (
"encoding/json"
"fmt"
"net/http"
)
// HandlerRequest will be json decoded
// into by Handler
type HandlerRequest struct {
Name string `json:"name"`
}
// Handler takes a request and renders a response
func Handler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
if r.Method != http.MethodPost {
w.WriteHeader(http.StatusMethodNotAllowed)
return
}
dec := json.NewDecoder(r.Body)
var req HandlerRequest
if err := dec.Decode(&req); err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte(fmt.Sprintf("BDD testing %s", req.Name)))
}
- Create a new directory called features, and create a file called features/handler.go with the following content:
Feature: Bad Method
Scenario: Good request
Given we create a HandlerRequest payload with:
| reader |
| coder |
| other |
And we POST the HandlerRequest to /hello
Then the response code should be 200
And the response body should be:
| BDD testing reader |
| BDD testing coder |
| BDD testing other |
- Run the godog command, and you will see the following output:
$ godog
.
1 scenarios (1 undefined)
4 steps (4 undefined)
89.062µs
.
- This should give you a skeleton to implement the tests that we wrote in our feature file; copy those into handler_test.go and implement the first two steps:
package bdd
import (
"bytes"
"encoding/json"
"fmt"
"net/http/httptest"
"github.com/DATA-DOG/godog"
"github.com/DATA-DOG/godog/gherkin"
)
var payloads []HandlerRequest
var resps []*httptest.ResponseRecorder
func weCreateAHandlerRequestPayloadWith(arg1
*gherkin.DataTable) error {
for _, row := range arg1.Rows {
h := HandlerRequest{
Name: row.Cells[0].Value,
}
payloads = append(payloads, h)
}
return nil
}
func wePOSTTheHandlerRequestToHello() error {
for _, p := range payloads {
v, err := json.Marshal(p)
if err != nil {
return err
}
w := httptest.NewRecorder()
r := httptest.NewRequest("POST", "/hello",
bytes.NewBuffer(v))
Handler(w, r)
resps = append(resps, w)
}
return nil
}
- Run the godog command, and you will see the following output:
$ godog
.
1 scenarios (1 pending)
4 steps (2 passed, 1 pending, 1 skipped)
.
- Fill in the remaining two steps:
func theResponseCodeShouldBe(arg1 int) error {
for _, r := range resps {
if got, want := r.Code, arg1; got != want {
return fmt.Errorf("got: %d; want %d", got, want)
}
}
return nil
}
func theResponseBodyShouldBe(arg1 *gherkin.DataTable) error {
for c, row := range arg1.Rows {
b := bytes.Buffer{}
b.ReadFrom(resps[c].Body)
if got, want := b.String(), row.Cells[0].Value;
got != want
{
return fmt.Errorf("got: %s; want %s", got, want)
}
}
return nil
}
func FeatureContext(s *godog.Suite) {
s.Step(`^we create a HandlerRequest payload with:$`,
weCreateAHandlerRequestPayloadWith)
s.Step(`^we POST the HandlerRequest to /hello$`,
wePOSTTheHandlerRequestToHello)
s.Step(`^the response code should be (d+)$`,
theResponseCodeShouldBe)
s.Step(`^the response body should be:$`,
theResponseBodyShouldBe)
}
- Run the godog command, and you will see the following output:
$ godog
.
1 scenarios (1 passed)
4 steps (4 passed)
552.605µs
.