Testify

repository·master·Indexed 12 days ago

https://github.com/stretchr/testify

A toolkit for Go providing tools for writing tests, including the assert and require packages for assertions, a mock package for creating mock objects, and a suite package for organizing tests into structs with setup and teardown logic.

Tokens
1.6K
Snippets
5
Records
7
Agent score
49%

What's inside Testify

  1. Build testing suites with the suite package

    master

    The suite package allows you to organize tests into structs, enabling setup/teardown logic and shared state.

    Key features:

    • Embed suite.Suite in your test struct.
    • Implement SetupTest() to run code before every test method.
    • All methods starting with Test are automatically run as tests.
    • The suite.Suite object provides built-in assertion methods (e.g., suite.Equal) so you don't need to pass t manually.
    • Note: The suite package does not support parallel tests.

    To run a suite, you must call suite.Run(t, new(YourSuiteStruct)) from a standard TestXxx(t *testing.T) function.

    import (
    	"testing"
    
    	"github.com/stretchr/testify/assert"
    	"github.com/stretchr/testify/suite"
    )
    
    type ExampleTestSuite struct {
    	suite.Suite
    	VariableThatShouldStartAtFive int
    }
    
    func (suite *ExampleTestSuite) SetupTest() {
    	suite.VariableThatShouldStartAtFive = 5
    }
    
    func (suite *ExampleTestSuite) TestExample() {
    	// Use built-in assertion methods on the suite object
    	suite.Equal(5, suite.VariableThatShouldStartAtFive)
    }
    
    func TestExampleTestSuite(t *testing.T) {
    	suite.Run(t, new(ExampleTestSuite))
    }
  2. Create mocks with the mock package

    master

    The mock package allows you to create mock objects that implement interfaces. You can set expectations on method calls and verify them later.

    Workflow:

    1. Embed mock.Mock in your struct.
    2. Implement the interface methods using m.Called(args...).
    3. Use .On("MethodName", args).Return(returns...) to set expectations.
    4. Use .AssertExpectations(t) to verify that all expected calls occurred.

    Use mock.Anything as a placeholder when the exact argument value is unknown or dynamic.

    package yours
    
    import (
    	"testing"
    
    	"github.com/stretchr/testify/mock"
    )
    
    type MyMockedObject struct {
    	mock.Mock
    }
    
    func (m *MyMockedObject) DoSomething(number int) (bool, error) {
    	args := m.Called(number)
    	return args.Bool(0), args.Error(1)
    }
    
    func TestSomething(t *testing.T) {
    	testObj := new(MyMockedObject)
    
    	// Set expectation with a specific value
    	testObj.On("DoSomething", 123).Return(true, nil)
    
    	// OR set expectation with a placeholder
    	testObj.On("DoSomething", mock.Anything).Return(true, nil)
    
    	// Call the code under test
    	targetFuncThatDoesSomethingWithObj(testObj)
    
    	// Verify expectations
    	testObj.AssertExpectations(t)
    }
  3. Overview of the testify module packages

    master

    The testify module is a collection of packages designed to improve Go testing workflows. It provides tools for assertions, mocking, and structured test suites. The module is composed of four primary packages:

    • github.com/stretchr/testify/assert: Provides a comprehensive set of assertion functions that integrate with the standard Go testing system. These functions allow tests to continue even if an assertion fails.
    • github.com/stretchr/testify/require: Provides the same set of assertions as the assert package, but treats failures as fatal checks (calling t.FailNow()), which stops the execution of the current test immediately.
    • github.com/stretchr/testify/mock: A framework for creating mock objects and verifying that specific method calls occur with expected arguments.
    • github.com/stretchr/testify/suite: Provides a structure for organizing tests into suites using structs. It supports setup and teardown logic through specific interfaces.
  4. Use the require package for terminating assertions

    master

    The require package provides the same global functions as assert, but instead of returning a boolean, they call t.FailNow() to terminate the current test immediately upon failure.

    Warning: These functions must be called from the goroutine running the test or benchmark function. Calling them from other goroutines may cause race conditions.

  5. Use the assert package for non-terminating assertions

    master

    The assert package provides methods that print friendly failure descriptions but allow the test to continue executing.

    Key behaviors:

    • Every assertion function takes *testing.T as the first argument.
    • Every assertion function returns a bool indicating success or failure, which can be used to gate subsequent logic.
    • You can use assert.New(t) to create an assertion object that doesn't require passing t to every subsequent call.
    package yours
    
    import (
    	"testing"
    
    	"github.com/stretchr/testify/assert"
    )
    
    func TestSomething(t *testing.T) {
    	// Using global functions
    	assert.Equal(t, 123, 123, "they should be equal")
    
    	// Using an assertion object for cleaner code
    	assert := assert.New(t)
    	assert.Equal(123, 123, "they should be equal")
    
    	// Using the boolean return value to safely proceed
    	if assert.NotNil(t, object) {
    		assert.Equal(t, "Something", object.Value)
    	}
    }