Github.com/stretchr/testify
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
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, declared as follows:
package somepkg
type Something interface {
SomeFunc(s string, i int) (string, error)
SomeOtherFunc(s string) (string, error)
}
In the somepkg_mocks_test.go
define the SomethingMock
struct as a wrapper around the Testify mock.Mock
structure and implement all the methods that are used in testing according to the following pattern. If we know for sure that a method will not be exercised in testing, it is fine to let it panic("not yet implemented")
:
package somepkg
// The mock structure wraps around the mock.Mock structure, which provides all mock functionality. Once instantiated
// such a structure can be used to "configure" the mock behavior, also known as "expectations", using methods like On().
// After the mock was used, the method AssertExpectations() is invoked to [...]
type SomethingMock struct {
mock.Mock
}