Documentation
¶
Overview ¶
Package testutils contains helper functions and utilities to assist with running tests. These functions are designed to simplify test setup, teardown, and common tasks required during unit and integration testing in Go.
It includes utilities for mocking, creating test data, and other commonly needed operations that can help make test code more readable, reusable, and maintainable. Example usage:
testutils.NewTestStore(t, db) // Set up a test store that rolls back all changes after a test run.
Index ¶
- Variables
- func CreateTestOrganization(ctx context.Context, appStore store.Store, isActive bool, role *models.Role, ...) (*models.Organization, error)
- func CreateTestOrganizationMember(ctx context.Context, appStore store.Store, orgID, roleID, userID int64) (*models.OrganizationMember, error)
- func CreateTestRole(ctx context.Context, appStore store.Store, isDeleted bool, orgID int64, ...) (*models.Role, error)
- func GenerateDate() string
- func GenerateEmailAndUsername() (email string, username string)
- func GenerateTesAuthToken(authenticator auth.Authenticator, cfg config.AuthConfig, isValid bool, ...) (string, error)
- func NewTestStore(t *testing.T, db *sql.DB) store.Store
- type ClaimsDetails
- type TestRequestData
- type TestRequestHeaders
- type TestRequestResponse
- type TestResponseData
- type TestUserData
Constants ¶
This section is empty.
Variables ¶
var ( TestPassword = "C0mpl3x_P@ssw0rD" TestProfilePic = "https://fake.link.org/pfp.png" )
Functions ¶
func CreateTestOrganization ¶
func CreateTestRole ¶
func GenerateDate ¶
func GenerateDate() string
GenerateDate generates a random date in the format "mm/dd/yyyy" using the faker package. The function splits the generated date string (in the format "yyyy-mm-dd") and reformats it to "mm/dd/yyyy" to comply with the desired format.
Returns:
- A string representing the randomly generated date in "mm/dd/yyyy" format.
Example usage:
date := GenerateDate() fmt.Println("Generated date:", date) // Output: "03/15/2025"
func GenerateEmailAndUsername ¶
GenerateEmailAndUsername generates a unique email and username using the faker package. The function uses the faker library to create a random, unique username and then formats it into an email address.
Returns:
- email: A randomly generated email address formatted as "<username>@clone.meetup.org".
- username: A randomly generated username. This is used as the local part of the email address.
Example usage:
email, username := GenerateEmailAndUsername() fmt.Println("Generated email:", email) fmt.Println("Generated username:", username)
func GenerateTesAuthToken ¶
func GenerateTesAuthToken(authenticator auth.Authenticator, cfg config.AuthConfig, isValid bool, ID int64) (string, error)
func NewTestStore ¶
NewTestStore sets up a test store for running tests that interacts with a real database. It ensures that all changes made during the test are rolled back after the test completes. This is achieved by using a database transaction, so any database modifications (inserts, updates, deletes) performed during the test will not persist beyond the test run.
Parameters:
- t (testing.T): The test instance provided by the testing framework, used for managing test state.
- db (*sql.DB): The database connection to be used by the test store.
Returns:
- store.Store: A store instance configured for testing. It uses transactions that will be rolled back after the test completes.
Example usage:
func TestCreateUser(t *testing.T) { testStore := NewTestStore(t, db) // Use testStore to interact with the database during the test // At the end of the test, all changes to the database will be rolled back
Types ¶
type ClaimsDetails ¶
type TestRequestData ¶
TestRequestData represents the request payload for a test HTTP request. It uses a flexible map structure to allow arbitrary key-value pairs for building request bodies.
type TestRequestHeaders ¶
TestRequestHeaders represents a collection of HTTP headers for test requests. It is a map where the key is the header name and the value is the header value.
Example:
headers := TestRequestHeaders{ "Authorization": "Bearer some.jwt.token", "Content-Type": "application/json", }
type TestRequestResponse ¶
type TestRequestResponse struct { Response *httptest.ResponseRecorder ResponseData TestResponseData }
TestRequestResponse wraps the result of an HTTP test request. It includes the raw response recorder and the parsed response data.
Fields:
- Response (*httptest.ResponseRecorder): Captures the HTTP response for status, headers, and body.
- ResponseData (TestResponseData): The decoded JSON response body.
func RunTestRequest ¶
func RunTestRequest(mux http.Handler, method, endpoint string, headers TestRequestHeaders, data TestRequestData) (*TestRequestResponse, error)
RunTestRequest performs a test HTTP request and returns the result.
It marshals the provided request data to JSON, sets the appropriate content type, and executes the request against the given HTTP handler (mux). The function then captures the response and unmarshals the JSON response body for easier assertions.
Parameters:
- mux (http.Handler): The HTTP handler to serve the request (e.g., your router).
- method (string): The HTTP method to use (e.g., "GET", "POST", "PUT", "DELETE").
- endpoint (string): The API endpoint to test (e.g., "/api/login").
- headers (TestRequestHeaders): The headers to include in the request (e.g., authorization, content type).
- data (TestRequestData): The request payload, which will be marshaled to JSON.
Returns:
- *TestRequestResponse: Contains the HTTP response recorder and the parsed response data.
- error: An error if request creation, execution, or response decoding fails.
Example usage:
res, err := RunTestRequest( router, "/login", "POST", TestRequestHeaders{"Authorization": "Bearer some.jwt.token"}, TestRequestData{ "email": "test@example.com", "password": "password123", }) if err != nil { log.Fatal(err) } fmt.Println(res.Response.Code) // prints the HTTP status code fmt.Println(res.ResponseData["message"]) // prints the response message
func (*TestRequestResponse) GetData ¶
func (r *TestRequestResponse) GetData() (map[string]any, bool)
GetData extracts the "data" field from the response data.
This method returns the response data as a map, along with a boolean indicating success. If the "data" field isn't present or isn't a map, it returns false.
Returns:
- map[string]any: The data from the response.
- bool: True if the "data" field was found and is a map, false otherwise.
Example usage:
res, _ := RunTestRequest(router, "GET", "/profile", nil, nil) if data, ok := res.GetData(); ok { fmt.Println(data) // prints the response data }
func (*TestRequestResponse) GetErrorMessages ¶
func (r *TestRequestResponse) GetErrorMessages() (map[string]any, bool)
GetErrorMessages extracts the "errors" field from the response data.
This method returns the error messages as a map, along with a boolean indicating success. If the "errors" field isn't present or isn't a map, it returns false.
Returns:
- map[string]any: The error messages from the response.
- bool: True if the "errors" field was found and is a map, false otherwise.
Example usage:
res, _ := RunTestRequest(router, "POST", "/register", nil, requestData) if errors, ok := res.GetErrorMessages(); ok { fmt.Println(errors) // prints the error messages }
func (*TestRequestResponse) GetMessage ¶
func (r *TestRequestResponse) GetMessage() string
GetMessage extracts the "message" field from the response data.
This method checks if the "message" field exists and is a string. If the field is missing or not a string, it returns an empty string.
Returns:
- string: The message string from the response, or an empty string if not found or invalid.
Example usage:
res, _ := RunTestRequest(router, "POST", "/login", nil, requestData) fmt.Println(res.GetMessage()) // prints the message from the response, or an empty string
func (*TestRequestResponse) StatusCode ¶
func (r *TestRequestResponse) StatusCode() int
StatusCode returns the HTTP status code from the response.
This method provides a convenient way to access the status code of the test HTTP response. If the response is nil, it returns nil to avoid panics.
Returns:
- *int: A pointer to the status code, or nil if the response is not set.
Example usage:
res, _ := RunTestRequest(router, "GET", "/users", nil, nil) if statusCode := res.StatusCode(); statusCode != nil { fmt.Println(*statusCode) // prints the HTTP status code }
type TestResponseData ¶
TestResponseData represents the response body of a test HTTP request. Like the request, it uses a map to handle dynamic response structures.
type TestUserData ¶
TestUserData holds the data required to create a test user. It is typically used for setting up mock or test user data in unit tests or integration tests.
Fields:
- Email: The email address of the test user. This field is used to create a user in the system, and should be unique for each test case.
- Username: The username for the test user. It can be any string value used in the user creation process.
- Password: The password for the test user. This should be a valid password string used for testing login and authentication logic.
- Activate: A boolean flag indicating whether the user should be activated upon creation. If true, the user will be marked as activated; otherwise, they will remain inactive.
Example usage:
testData := TestUserData{ Email: "testuser@example.com", Username: "testuser", Password: "securePassword123", Activate: true, }
func NewTestUserData ¶
func NewTestUserData(activate bool) TestUserData
NewTestUserData generates a new instance of TestUserData with a random email, username, a predefined test password, and an activation status based on the `activate` argument.
This function utilizes the `GenerateEmailAndUsername` function to generate a unique email and username, and sets a default test password (`TestPassword`) while allowing the caller to specify whether the user should be activated or not.
Parameters:
- activate (bool): A flag indicating whether the user should be activated or not.
Returns:
- A `TestUserData` struct populated with the generated email, username, password, and activation status.
Example usage:
userData := NewTestUserData(true) fmt.Println(userData.Email, userData.Username, userData.Activate)
func (TestUserData) CreateDeactivatedTestUser ¶
func (c TestUserData) CreateDeactivatedTestUser(ctx context.Context, store store.Store, role models.UserRole) (*models.User, error)
CreateDeactivatedTestUser creates a new user with a deactivated state for testing purposes. The user is created with the specified details, and the `IsActive` field is set to `false`. The `ActivatedAt` field is set to `time.Now()` to simulate a deactivated user.
Parameters:
- ctx (context.Context): The context for managing cancellation and deadlines.
- store (store.Store): The store object that handles the interaction with the database.
Returns:
- *models.User: The created user object with the deactivated state.
- error: An error if the user creation fails, or nil if the creation is successful.
func (TestUserData) CreateTestUser ¶
func (c TestUserData) CreateTestUser(ctx context.Context, appStore store.Store, role models.UserRole) (*models.User, *models.UserProfile, error)
CreateTestUser creates a test user and their associated profile in the database using the provided store. The method interacts with the `store` to save the user and user profile data, returning the created `User` and `UserProfile` models along with any errors encountered during the process.
Parameters:
- ctx (context.Context): The context to associate with the database operation.
- store (store.Store): The store instance used to interact with the database to create the user and profile.
Returns:
- *models.User: The created `User` model.
- *models.UserProfile: The created `UserProfile` model.
- error: Any error that occurred during the creation process, or nil if successful.
Example usage:
userData := NewTestUserData(true) user, profile, err := userData.CreateTestUser(ctx, store) if err != nil { log.Fatal(err) } fmt.Println("User created:", user, "Profile created:", profile)