Skip to main content
Version: testcontainers_v0.x.x

Testcontainers

Release Discord Test

A Testcontainers Service Implementation for Fiber.

note

Requires Go 1.23 and above

Common Use Cases

  • Local development
  • Integration testing
  • Isolated service testing
  • End-to-end testing

Install

caution

This Service Implementation only supports Fiber v3.

go get -u github.com/gofiber/fiber/v3
go get -u github.com/gofiber/contrib/testcontainers

Signature

NewModuleConfig

// NewModuleConfig creates a new container service config for a module.
//
// - The serviceKey is the key used to identify the service in the Fiber app's state.
// - The img is the image name to use for the container.
// - The run is the function to use to run the container. It's usually the Run function from the module, like [redis.Run] or [postgres.Run].
// - The opts are the functional options to pass to the run function. This argument is optional.
func NewModuleConfig[T testcontainers.Container](
serviceKey string,
img string,
run func(ctx context.Context, img string, opts ...testcontainers.ContainerCustomizer) (T, error),
opts ...testcontainers.ContainerCustomizer,
) Config[T] {

NewContainerConfig

// NewContainerConfig creates a new container service config for a generic container type,
// not created by a Testcontainers module. So this function best used in combination with
// the [AddService] function to add a custom container to the Fiber app's state.
//
// - The serviceKey is the key used to identify the service in the Fiber app's state.
// - The img is the image name to use for the container.
// - The opts are the functional options to pass to the [testcontainers.Run] function. This argument is optional.
//
// This function uses the [testcontainers.Run] function as the run function.
func NewContainerConfig[T *testcontainers.DockerContainer](serviceKey string, img string, opts ...testcontainers.ContainerCustomizer) Config[*testcontainers.DockerContainer]

AddService

// AddService adds a Testcontainers container as a [fiber.Service] for the Fiber app.
// It returns a pointer to a [ContainerService[T]] object, which contains the key used to identify
// the service in the Fiber app's state, and an error if the config is nil.
// The container should be a function like redis.Run or postgres.Run that returns a container type
// which embeds [testcontainers.Container].
// - The cfg is the Fiber app's configuration, needed to add the service to the Fiber app's state.
// - The containerConfig is the configuration for the container, where:
// - The containerConfig.ServiceKey is the key used to identify the service in the Fiber app's state.
// - The containerConfig.Run is the function to use to run the container. It's usually the Run function from the module, like redis.Run or postgres.Run.
// - The containerConfig.Image is the image to use for the container.
// - The containerConfig.Options are the functional options to pass to the [testcontainers.Run] function. This argument is optional.
//
// Use [NewModuleConfig] or [NewContainerConfig] helper functions to create valid containerConfig objects.
func AddService[T testcontainers.Container](cfg *fiber.Config, containerConfig Config[T]) (*ContainerService[T], error) {

Types

Config

The Config type is a generic type that is used to configure the container.

PropertyTypeDescriptionDefault
ServiceKeystringThe key used to identify the service in the Fiber app's state.-
ImagestringThe image name to use for the container.-
Runfunc(ctx context.Context, img string, opts ...testcontainers.ContainerCustomizer) (T, error)The function to use to run the container. It's usually the Run function from the testcontainers-go module, like redis.Run or postgres.Run-
Options[]testcontainers.ContainerCustomizerThe functional options to pass to the [testcontainers.Run] function. This argument is optional.-
// Config contains the configuration for a container service.
type Config[T testcontainers.Container] struct {
// ServiceKey is the key used to identify the service in the Fiber app's state.
ServiceKey string

// Image is the image name to use for the container.
Image string

// Run is the function to use to run the container.
// It's usually the Run function from the testcontainers-go module, like redis.Run or postgres.Run,
// although it could be the generic [testcontainers.Run] function from the testcontainers-go package.
Run func(ctx context.Context, img string, opts ...testcontainers.ContainerCustomizer) (T, error)

// Options are the functional options to pass to the [testcontainers.Run] function. This argument is optional.
// You can find the available options in the [testcontainers website].
//
// [testcontainers website]: https://golang.testcontainers.org/features/creating_container/#customizing-the-container
Options []testcontainers.ContainerCustomizer
}

ContainerService

The ContainerService type is a generic type that embeds a testcontainers.Container interface, and implements the [fiber.Service] interface, thanks to the Start, String, State and Terminate methods. It manages the lifecycle of a testcontainers.Container instance, and it can be retrieved from the Fiber app's state calling the fiber.MustGetService function with the key returned by the ContainerService.Key method.

The type parameter T must implement the testcontainers.Container interface, as in the Testcontainers Go modules (e.g. redis.RedisContainer, postgres.PostgresContainer, etc.), or in the generic testcontainers.DockerContainer type, used for custom containers.

note

Since ContainerService implements the fiber.Service interface, container cleanup is handled automatically by the Fiber framework when the application shuts down. There's no need for manual cleanup code.

type ContainerService[T testcontainers.Container] struct

Signature

 Key
// Key returns the key used to identify the service in the Fiber app's state.
// Consumers should use string constants for service keys to ensure consistency
// when retrieving services from the Fiber app's state.
func (c *ContainerService[T]) Key() string
Container
// Container returns the Testcontainers container instance, giving full access to the T type methods.
// It's useful to access the container's methods, like [testcontainers.Container.MappedPort]
// or [testcontainers.Container.Inspect].
func (c *ContainerService[T]) Container() T
Start
// Start creates and starts the container, calling the [run] function with the [img] and [opts] arguments.
// It implements the [fiber.Service] interface.
func (c *ContainerService[T]) Start(ctx context.Context) error
String
// String returns the service key, which uniquely identifies the container service.
// It implements the [fiber.Service] interface.
func (c *ContainerService[T]) String() string
State
// State returns the status of the container.
// It implements the [fiber.Service] interface.
func (c *ContainerService[T]) State(ctx context.Context) (string, error)
Terminate
// Terminate stops and removes the container. It implements the [fiber.Service] interface.
func (c *ContainerService[T]) Terminate(ctx context.Context) error

Common Errors

ErrorDescriptionResolution
ErrNilConfigReturned when the config is nilEnsure config is properly initialized
ErrContainerNotRunningReturned when the container is not runningCheck container state before operations
ErrEmptyServiceKeyReturned when the service key is emptyProvide a non-empty service key
ErrImageEmptyReturned when the image is emptyProvide a valid image name
ErrRunNilReturned when the run is nilProvide a valid run function

Examples

You can find more examples in the testable examples.

Adding a module container using the Testcontainers Go's Redis module

package main

import (
"fmt"
"log"

"github.com/gofiber/fiber/v3"

"github.com/gofiber/contrib/testcontainers"
tc "github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/modules/redis"
)

func main() {
cfg := &fiber.Config{}

// Define the base key for the module service.
// The service returned by the [testcontainers.AddService] function,
// using the [ContainerService.Key] method,
// concatenates the base key with the "using testcontainers-go" suffix.
const (
redisKey = "redis-module"
)

// Adding containers coming from the testcontainers-go modules,
// in this case, a Redis and a Postgres container.

redisModuleConfig := testcontainers.NewModuleConfig(redisKey, "redis:latest", redis.Run)
redisSrv, err := testcontainers.AddService(cfg, redisModuleConfig)
if err != nil {
log.Println("error adding redis module:", err)
return
}

// Create a new Fiber app, using the provided configuration.
app := fiber.New(*cfg)

// Retrieve all services from the app's state.
// This returns a slice of all the services registered in the app's state.
srvs := app.State().Services()

// Retrieve the Redis container from the app's state using the key returned by the [ContainerService.Key] method.
redisCtr := fiber.MustGetService[*testcontainers.ContainerService[*redis.RedisContainer]](app.State(), redisSrv.Key())

// Start the Fiber app.
app.Listen(":3000")
}

Adding a custom container using the Testcontainers Go package

package main

import (
"fmt"
"log"

"github.com/gofiber/fiber/v3"

"github.com/gofiber/contrib/testcontainers"
tc "github.com/testcontainers/testcontainers-go"
)

func main() {
cfg := &fiber.Config{}

// Define the base key for the generic service.
// The service returned by the [testcontainers.AddService] function,
// using the [ContainerService.Key] method,
// concatenates the base key with the "using testcontainers-go" suffix.
const (
nginxKey = "nginx-generic"
)

// Adding a generic container, directly from the testcontainers-go package.
containerConfig := testcontainers.NewContainerConfig(nginxKey, "nginx:latest", tc.WithExposedPorts("80/tcp"))

nginxSrv, err := testcontainers.AddService(cfg, containerConfig)
if err != nil {
log.Println("error adding nginx generic:", err)
return
}

app := fiber.New(*cfg)

nginxCtr := fiber.MustGetService[*testcontainers.ContainerService[*tc.DockerContainer]](app.State(), nginxSrv.Key())

// Start the Fiber app.
app.Listen(":3000")
}