MongoDB Go Driver V1 included the mtest
package allowing developers to mock driver responses in memory. A few popular blog posts since emerged detailing how to do this, including "How I'm testing MongoDB calls in Go (for now)" by Liza Shulyayeva. In V1, GODRIVER-1767 marked mtest
unstable so that the driver team could alter the API to accommodate new testing requirements. In V2, GODRIVER-2724 internalized mtest
making the V1 solution for mocking using mtest
unavailable.
Mocking can be overly complex and is brittle (AKA “Mock Hell”). Tests should be focused on your code, not the internals of the Go Driver. Since mocks are not identical to your live environment, problems can stay hidden longer. By the time an issue shows up in production, fixing it can be far more costly than if you’d caught it earlier in a more realistic test. Instead, it's better to use a container-based integration testing framework like testcontainers:
func TestMyRepositoryFunction(t *testing.T) {
ctx := context.Background()
// Start up a MongoDB container
req := testcontainers.ContainerRequest{
Image: "mongo:latest",
ExposedPorts: []string{"27017/tcp"},
WaitingFor: wait.ForLog("Waiting for connections").WithStartupTimeout(30 * time.Second),
}
mongoC, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
require.NoError(t, err)
defer mongoC.Terminate(ctx)
// Get mapped host & port
host, err := mongoC.Host(ctx)
require.NoError(t, err)
port, err := mongoC.MappedPort(ctx, "27017")
require.NoError(t, err)
// Connect with the Go driver
uri := fmt.Sprintf("mongodb://%s:%s", host, port.Port())
client, err := mongo.Connect(options.Client().ApplyURI(uri))
require.NoError(t, err)
defer client.Disconnect(ctx)
err := MyRepositoryFunction(context.TODO(), client.Database("mydb").Collection("mycoll"))
assert.NoError(t, err, "Should have successfully run")
}
For necessary edge cases V2 provides a MockDeployment
option in the experimental API which may be modified or removed without notice. Here is a re-worked example from this StackOverflow answer for V2:
func TestMyRepositoryFunction(t *testing.T) {
mockDep := drivertest.NewMockDeployment()
mockDep.AddResponses(
bson.D{{Key: "ok", Value: "1"}},
bson.D{
{Key: "ok", Value: "1"},
{Key: "value", Value: bson.M{"_id": "custom123", "key": 24}},
})
opts := options.Client()
opts.Deployment = mockDep
client, err := mongo.Connect(opts)
require.NoError(t, err)
defer client.Disconnect(ctx)
err := MyRepositoryFunction(context.TODO(), client.Database("mydb").Collection("mycoll"))
assert.NoError(t, err, "Should have successfully run")
}
Top comments (1)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.