Testcontainers implementation for Microsoft SQL Server providing lightweight, throwaway database instances for Java tests using Docker containers.
npx @tessl/cli install tessl/maven-org-testcontainers--mssqlserver@1.21.0Testcontainers implementation for Microsoft SQL Server providing lightweight, throwaway database instances for Java tests using Docker containers. Supports both traditional JDBC and reactive R2DBC connectivity patterns with automatic license handling and secure configuration.
implementation 'org.testcontainers:mssqlserver:1.21.3' (Gradle) or <dependency><groupId>org.testcontainers</groupId><artifactId>mssqlserver</artifactId><version>1.21.3</version></dependency> (Maven)import org.testcontainers.containers.MSSQLServerContainer;
import org.testcontainers.containers.MSSQLServerContainerProvider;
import org.testcontainers.containers.MSSQLR2DBCDatabaseContainer;
import org.testcontainers.containers.MSSQLR2DBCDatabaseContainerProvider;import org.testcontainers.containers.MSSQLServerContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
@Testcontainers
public class DatabaseTest {
@Container
static MSSQLServerContainer<?> mssqlserver = new MSSQLServerContainer<>("mcr.microsoft.com/mssql/server:2019-latest")
.acceptLicense()
.withPassword("MyStr0ngPassword!");
@Test
void testConnection() throws SQLException {
String jdbcUrl = mssqlserver.getJdbcUrl();
String username = mssqlserver.getUsername();
String password = mssqlserver.getPassword();
try (Connection conn = DriverManager.getConnection(jdbcUrl, username, password)) {
// Test database operations
}
}
}The MSSQL Server module is built around several key components:
MSSQLServerContainer provides traditional JDBC database access with automatic configurationMSSQLR2DBCDatabaseContainer offers reactive database access using R2DBC driversMain container class for Microsoft SQL Server providing traditional JDBC connectivity with automatic configuration and lifecycle management.
public class MSSQLServerContainer<SELF extends MSSQLServerContainer<SELF>> extends JdbcDatabaseContainer<SELF> {
// Public constants
@Deprecated
public static final String DEFAULT_TAG = "2017-CU12";
public static final String NAME = "sqlserver";
public static final String IMAGE = "mcr.microsoft.com/mssql/server";
public static final Integer MS_SQL_SERVER_PORT = 1433;
// Package-private constants (accessible in same package)
static final String DEFAULT_USER = "sa";
static final String DEFAULT_PASSWORD = "A_Str0ng_Required_Password";
// Constructors
@Deprecated
public MSSQLServerContainer();
public MSSQLServerContainer(String dockerImageName);
public MSSQLServerContainer(DockerImageName dockerImageName);
// Configuration methods
public SELF acceptLicense();
public SELF withPassword(String password);
// Connection methods
public String getDriverClassName();
public String getJdbcUrl();
public String getUsername();
public String getPassword();
public String getTestQueryString();
public Set<Integer> getLivenessCheckPortNumbers();
}Usage Examples:
// Basic setup with license acceptance
MSSQLServerContainer<?> mssqlserver = new MSSQLServerContainer<>("mcr.microsoft.com/mssql/server:2019-latest")
.acceptLicense()
.withPassword("MyStr0ngPassword!");
mssqlserver.start();
// Get connection details
String jdbcUrl = mssqlserver.getJdbcUrl();
String username = mssqlserver.getUsername(); // Always "sa"
String password = mssqlserver.getPassword();
// Use with DataSource
HikariConfig config = new HikariConfig();
config.setJdbcUrl(jdbcUrl);
config.setUsername(username);
config.setPassword(password);
config.setDriverClassName(mssqlserver.getDriverClassName());Factory class for creating JDBC-based MS SQL Server containers, enabling framework integration and programmatic container creation.
public class MSSQLServerContainerProvider extends JdbcDatabaseContainerProvider {
public boolean supports(String databaseType);
public JdbcDatabaseContainer<?> newInstance();
public JdbcDatabaseContainer<?> newInstance(String tag);
}Usage Examples:
// Using provider for framework integration
MSSQLServerContainerProvider provider = new MSSQLServerContainerProvider();
if (provider.supports("sqlserver")) {
JdbcDatabaseContainer<?> container = provider.newInstance("2019-latest");
container.start();
}R2DBC wrapper providing reactive database access by wrapping an existing MSSQLServerContainer with reactive connectivity options.
public class MSSQLR2DBCDatabaseContainer implements R2DBCDatabaseContainer {
// Constructor
public MSSQLR2DBCDatabaseContainer(MSSQLServerContainer<?> container);
// Configuration methods
public static ConnectionFactoryOptions getOptions(MSSQLServerContainer<?> container);
public ConnectionFactoryOptions configure(ConnectionFactoryOptions options);
// Lifecycle methods (delegated to underlying container)
public void start();
public void stop();
public boolean isRunning();
}Usage Examples:
// Create R2DBC container from existing JDBC container
MSSQLServerContainer<?> jdbcContainer = new MSSQLServerContainer<>("mcr.microsoft.com/mssql/server:2019-latest")
.acceptLicense()
.withPassword("MyStr0ngPassword!");
MSSQLR2DBCDatabaseContainer r2dbcContainer = new MSSQLR2DBCDatabaseContainer(jdbcContainer);
r2dbcContainer.start();
// Get R2DBC connection options
ConnectionFactoryOptions options = r2dbcContainer.configure(
MSSQLR2DBCDatabaseContainer.getOptions(jdbcContainer)
);
// Create R2DBC connection factory
ConnectionFactory connectionFactory = ConnectionFactories.get(options);Factory class for creating R2DBC-based MS SQL Server containers from connection options, enabling reactive framework integration.
public class MSSQLR2DBCDatabaseContainerProvider implements R2DBCDatabaseContainerProvider {
// Package-private constants
static final String DRIVER = "mssql"; // R2DBC driver identifier
// Provider methods
public boolean supports(ConnectionFactoryOptions options);
public R2DBCDatabaseContainer createContainer(ConnectionFactoryOptions options);
public ConnectionFactoryMetadata getMetadata(ConnectionFactoryOptions options);
}Usage Examples:
// Using provider for R2DBC framework integration
ConnectionFactoryOptions options = ConnectionFactoryOptions.builder()
.option(DRIVER, "mssql")
.option(HOST, "localhost")
.option(DATABASE, "test")
.build();
MSSQLR2DBCDatabaseContainerProvider provider = new MSSQLR2DBCDatabaseContainerProvider();
if (provider.supports(options)) {
R2DBCDatabaseContainer container = provider.createContainer(options);
container.start();
}// Core types from Testcontainers framework
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.containers.JdbcDatabaseContainerProvider;
import org.testcontainers.r2dbc.R2DBCDatabaseContainer;
import org.testcontainers.r2dbc.R2DBCDatabaseContainerProvider;
import org.testcontainers.utility.DockerImageName;
import org.testcontainers.lifecycle.Startable;
// R2DBC types
import io.r2dbc.spi.ConnectionFactory;
import io.r2dbc.spi.ConnectionFactories;
import io.r2dbc.spi.ConnectionFactoryOptions;
import io.r2dbc.spi.ConnectionFactoryMetadata;
// Standard Java types
import java.util.Set;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;The MSSQL Server container handles several types of errors:
IllegalArgumentException thrown for passwords that don't meet SQL Server requirements (8-128 characters, 3+ character categories)ACCEPT_EULA=Y is not set via acceptLicense() methodCommon Error Patterns:
try {
MSSQLServerContainer<?> container = new MSSQLServerContainer<>("mcr.microsoft.com/mssql/server:2019-latest")
.withPassword("weak"); // Will throw IllegalArgumentException
} catch (IllegalArgumentException e) {
// Handle password validation error
System.err.println("Password does not meet SQL Server requirements: " + e.getMessage());
}
// Always accept license to avoid startup failures
container.acceptLicense(); // Required for successful container startup