Advanced testdeep technique

Of course we can test struct fields one by one, but with testdeep, the whole struct can be compared with one Cmp call.

We can choose to ignore the non-guessable fields set by CreateRecord():

import (
  "testing"
  "time"

  td "github.com/maxatome/go-testdeep"
)

func TestCreateRecord(t *testing.T) {
  before := time.Now().Truncate(time.Second)
  record, err := CreateRecord()

  if td.CmpNoError(t, err) {
    td.Cmp(t, record,
      td.Struct(
        &Record{
          Name: "Bob",
          Age:  23,
        },
        nil),
      "Newly created record")
  }
}

The Struct operator, used here, ignores zero fields in its model parameter.

But it is better to check all fields:

import (
  "testing"
  "time"

  td "github.com/maxatome/go-testdeep"
)

func TestCreateRecord(t *testing.T) {
  before := time.Now().Truncate(time.Second)
  record, err := CreateRecord()

  if td.CmpNoError(t, err) {
    td.Cmp(t, record,
      td.Struct(
        &Record{
          Name: "Bob",
          Age:  23,
        },
        td.StructFields{
          "Id":        td.NotZero(),
          "CreatedAt": td.Between(before, time.Now()),
        }),
      "Newly created record")
  }
}

See the use of the Struct operator. It is needed here to overcome the go static typing system and so use other testdeep operators for some fields, here NotZero for Id and Between for CreatedAt.

Not only structs can be compared. A lot of operators can be found to cover most (all?) needed tests. See the operators list.

Say CreateRecord() does not set correctly CreatedAt field, then:

go test -run=TestCreateRecord

outputs for last td.Cmp call:

error output

If CreateRecord() had not set correctly Id field, output would have been:

error output

If CreateRecord() had set Name field to “Alice” value instead of expected “Bob”, output would have been:

error output