Nats¶
Introduction¶
The Testcontainers module for nats.
Adding this module to your project dependencies¶
Please run the following command to add the nats module to your Go dependencies:
go get github.com/testcontainers/testcontainers-go/examples/nats
Usage example¶
package nats
import (
"context"
"fmt"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
)
// natsContainer represents the nats container type used in the module
type natsContainer struct {
testcontainers.Container
URI string
}
// runContainer creates an instance of the nats container type
func runContainer(ctx context.Context, opts ...testcontainers.ContainerCustomizer) (*natsContainer, error) {
req := testcontainers.ContainerRequest{
Image: "nats:2.9",
ExposedPorts: []string{"4222/tcp", "6222/tcp", "8222/tcp"},
Cmd: []string{"-DV", "-js"},
WaitingFor: wait.ForLog("Listening for client connections on 0.0.0.0:4222"),
}
genericContainerReq := testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
}
for _, opt := range opts {
opt.Customize(&genericContainerReq)
}
container, err := testcontainers.GenericContainer(ctx, genericContainerReq)
if err != nil {
return nil, err
}
mappedPort, err := container.MappedPort(ctx, "4222/tcp")
if err != nil {
return nil, err
}
hostIP, err := container.Host(ctx)
if err != nil {
return nil, err
}
uri:= fmt.Sprintf("nats://%s:%s", hostIP, mappedPort.Port())
return &natsContainer{Container: container, URI: uri}, nil
}
package nats
import (
"context"
"testing"
"github.com/nats-io/nats.go"
)
func TestNats(t *testing.T) {
ctx := context.Background()
container, err := runContainer(ctx)
if err != nil {
t.Fatal(err)
}
// Clean up the container after the test is complete
t.Cleanup(func() {
if err := container.Terminate(ctx); err != nil {
t.Fatalf("failed to terminate container: %s", err)
}
})
// perform assertions
nc, err := nats.Connect(container.URI)
if err != nil {
t.Fatalf("failed to connect to nats: %s", err)
}
defer nc.Close()
js, err := nc.JetStream()
if err != nil {
t.Fatalf("failed to create jetstream context: %s", err)
}
// add stream to nats
if _, err = js.AddStream(&nats.StreamConfig{
Name: "hello",
Subjects: []string{"hello"},
}); err != nil {
t.Fatalf("failed to add stream: %s", err)
}
// add subscriber to nats
sub, err := js.SubscribeSync("hello", nats.Durable("worker"))
if err != nil {
t.Fatalf("failed to subscribe to hello: %s", err)
}
// publish a message to nats
if _, err = js.Publish("hello", []byte("hello")); err != nil {
t.Fatalf("failed to publish hello: %s", err)
}
// wait for the message to be received
msg, err := sub.NextMsgWithContext(ctx)
if err != nil {
t.Fatalf("failed to get message: %s", err)
}
if string(msg.Data) != "hello" {
t.Fatalf("expected message to be 'hello', got '%s'", msg.Data)
}
}