Github.com/stretchr/testify: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
Line 64: Line 64:
===Defining the Mock===
===Defining the Mock===


It's a good idea to encapsulate the mock definition(s) in a package-level <code>*_mocks_test.go</code> file. If we're testing <code>somepkg</code> package, then the code lives in the <code>somepkg.go</code> file, the tests live in <code>somepkg_test.go</code> file and the mocks live in <code>somepkg_mocks_test.go</code>:
It's a good idea to encapsulate the mock definition(s) in a package-level <code>*_mocks_test.go</code> file. If we're testing a <code>somepkg</code> package, then the code lives in the <code>somepkg.go</code> file, the tests live in <code>somepkg_test.go</code> file and the mocks live in <code>somepkg_mocks_test.go</code>:


<font size=-2>
<font size=-2>

Revision as of 21:40, 6 March 2024

External

Internal

Overview

Installation

go get github.com/stretchr/testify

Programming Model

Assertions

package yours

import (
  "testing"
  tassert "github.com/stretchr/testify/assert"
)

func TestSomething(t *testing.T) {

  assert := tassert.New(t)

  // assert equality
  assert.Equal(123, 123, "they should be equal")

  // assert inequality
  assert.NotEqual(123, 456, "they should not be equal")

  // assert for nil (good for errors)
  assert.Nil(object)

  // assert for not nil (good when you expect something)
  if assert.NotNil(object) {

    // now we know that object isn't nil, we are safe to make
    // further assertions without causing any errors
    assert.Equal("Something", object.Value)
  }
}

To check that an error has the expected message:

err := ...
assert.NotNil(err)
assert.Equal(err.Error(), "expected message")

Mocks

https://pkg.go.dev/github.com/stretchr/testify/mock

Mocking with Testify is based on the assumption that we want to construct mock instances to replace in testing real instances, standing in for external dependencies, defined by interfaces.

The programming model requires to:

  • define such a mock instance
  • instantiate it with new() or &SomeInterfaceMock{}
  • configure its behavior, by configuring its responses to method invocations (Testify calls this "setting up expectations")
  • pass it to the code that needs to be tested
  • run the code that needs to be tested
  • ensure the code behave correctly, knowing that the mock returned what we instructed it to return
  • optionally, "assert expectations" on the mock.

Defining the Mock

It's a good idea to encapsulate the mock definition(s) in a package-level *_mocks_test.go file. If we're testing a somepkg package, then the code lives in the somepkg.go file, the tests live in somepkg_test.go file and the mocks live in somepkg_mocks_test.go:

.
└── internal
    └── somepkg
        ├── somepkg.go
        ├── somepkg_test.go
        └── somepkg_mocks_test.go

Assuming that the instances we want to mock are defined by the Something interface, defined as follows:

package somepkg

type Something interface {
	SomeFunc(s string, i int) (string, error)
	SomeOtherFunc(s string) (string, error)
}
...
type MockMyService struct {
	mock.Mock
}

func (m * MockMyService) Start() error {
  ...
}

...

mockMyService := new(MockMyService)