Let's go through a comprehensive example that covers common features of the stretchr/testify library and mockery for mocking in Golang. This example will include testing with assertions, using the require package for strict assertions, testing HTTP handlers, and mocking dependencies using mockery.
Imagine we have a service that fetches user information from an external API. We want to test:
/project │ ├── main.go ├── service.go ├── service_test.go ├── user_client.go ├── mocks/ │ └── UserClient.go (generated by mockery) └── go.mod
user_client.go
This file defines an interface for interacting with an external user API.
package project type User struct { ID int Name string } type UserClient interface { GetUserByID(id int) (*User, error) }
service.go
This file contains a service that uses the UserClient to fetch user details.
package project import "fmt" type UserService struct { client UserClient } func NewUserService(client UserClient) *UserService { return &UserService{client: client} } func (s *UserService) GetUserDetails(id int) (string, error) { user, err := s.client.GetUserByID(id) if err != nil { return "", fmt.Errorf("failed to get user: %w", err) } return fmt.Sprintf("User: %s (ID: %d)", user.Name, user.ID), nil }
Generating Mocks with mockery
You can generate mocks for the UserClient using mockery:
mockery --name=UserClient --output=./mocks
This will generate a mock in mocks/UserClient.go.
service_test.go
Now, let's write a test for the UserService using testify assertions and the mockery-generated mock.
package project_test import ( "errors" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/mock" "project" "project/mocks" ) func TestUserService_GetUserDetails_Success(t *testing.T) { // Create a new mock client mockClient := new(mocks.UserClient) // Define what the mock should return when `GetUserByID` is called mockClient.On("GetUserByID", 1).Return(&project.User{ ID: 1, Name: "John Doe", }, nil) // Create the UserService with the mock client service := project.NewUserService(mockClient) // Test the GetUserDetails method result, err := service.GetUserDetails(1) // Use `require` for error checks require.NoError(t, err) require.NotEmpty(t, result) // Use `assert` for value checks assert.Equal(t, "User: John Doe (ID: 1)", result) // Ensure that the `GetUserByID` method was called exactly once mockClient.AssertExpectations(t) } func TestUserService_GetUserDetails_Error(t *testing.T) { // Create a new mock client mockClient := new(mocks.UserClient) // Define what the mock should return when `GetUserByID` is called with an error mockClient.On("GetUserByID", 2).Return(nil, errors.New("user not found")) // Create the UserService with the mock client service := project.NewUserService(mockClient) // Test the GetUserDetails method result, err := service.GetUserDetails(2) // Use `require` for error checks require.Error(t, err) assert.Contains(t, err.Error(), "user not found") // Ensure that the result is empty assert.Empty(t, result) // Ensure that the `GetUserByID` method was called exactly once mockClient.AssertExpectations(t) }
This setup covers the basic functionality of stretchr/testify for assertions and mocking with mockery, providing a structured and maintainable approach to unit testing in Golang.
The above is the detailed content of GOLANG TESTING WITH STRETCHR/TESTIFY AND MOCKERY. For more information, please follow other related articles on the PHP Chinese website!