Skip to content

Commit

Permalink
feat: Add Respawn example (#1307)
Browse files Browse the repository at this point in the history
  • Loading branch information
HofmeisterAn authored Nov 25, 2024
1 parent 6051cdb commit aa8234d
Show file tree
Hide file tree
Showing 15 changed files with 208 additions and 5 deletions.
10 changes: 5 additions & 5 deletions examples/Flyway/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
</PropertyGroup>
<ItemGroup>
<!-- Unit and integration test dependencies: -->
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
<PackageVersion Include="Testcontainers.PostgreSql" Version="3.7.0"/>
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.7"/>
<PackageVersion Include="xunit" Version="2.7.0"/>
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.11.1"/>
<PackageVersion Include="Testcontainers.PostgreSql" Version="4.0.0"/>
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2"/>
<PackageVersion Include="xunit" Version="2.9.2"/>
<!-- Third-party client dependencies to connect and interact with the containers: -->
<PackageVersion Include="Npgsql" Version="6.0.10"/>
<PackageVersion Include="Npgsql" Version="6.0.11"/>
</ItemGroup>
</Project>
1 change: 1 addition & 0 deletions examples/Respawn/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
root = true
1 change: 1 addition & 0 deletions examples/Respawn/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto
25 changes: 25 additions & 0 deletions examples/Respawn/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<Version>0.1.0</Version>
<PackageId>$(AssemblyName)</PackageId>
<AssemblyVersion>$(Version)</AssemblyVersion>
<FileVersion>$(Version)</FileVersion>
<InformationalVersion>$(Version)</InformationalVersion>
<NeutralLanguage>en-US</NeutralLanguage>
<Authors>Andre Hofmeister</Authors>
<Company></Company>
<Description></Description>
<Summary></Summary>
<PackageIconUrl></PackageIconUrl>
<PackageLicenseExpression></PackageLicenseExpression>
<PackageProjectUrl></PackageProjectUrl>
<PackageTags></PackageTags>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/testcontainers/testcontainers-dotnet-sample</RepositoryUrl>
</PropertyGroup>
<PropertyGroup>
<LangVersion>10.0</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
16 changes: 16 additions & 0 deletions examples/Respawn/Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<!-- Unit and integration test dependencies: -->
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.11.1"/>
<PackageVersion Include="Testcontainers.PostgreSql" Version="4.0.0"/>
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.2"/>
<PackageVersion Include="xunit" Version="2.9.2"/>
<!-- Third-party client dependencies to connect and interact with the containers: -->
<PackageVersion Include="Npgsql" Version="6.0.11"/>
<PackageVersion Include="Respawn" Version="6.2.1"/>
</ItemGroup>
</Project>
9 changes: 9 additions & 0 deletions examples/Respawn/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Testcontainers for .NET Respawn example

This example demonstrates how to use Respawn to reset the state of a PostgreSQL database between tests, ensuring isolation and consistency. The `RespawnTest` test class interacts with a pre-configured database, using Respawn to clear the data before each test run. This allows the tests to execute in a clean environment without interfering with each other.

```console
git clone --branch develop [email protected]:testcontainers/testcontainers-dotnet.git
cd ./testcontainers-dotnet/examples/Respawn/
dotnet test Respawn.sln --configuration=Release
```
26 changes: 26 additions & 0 deletions examples/Respawn/Respawn.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{424CFC36-D6F7-4DBB-BD1C-0C84FE30E665}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Respawn.Tests", "tests\Respawn.Tests\Respawn.Tests.csproj", "{75E66E21-E169-4504-89FA-4784CB66DEB5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{75E66E21-E169-4504-89FA-4784CB66DEB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{75E66E21-E169-4504-89FA-4784CB66DEB5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{75E66E21-E169-4504-89FA-4784CB66DEB5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{75E66E21-E169-4504-89FA-4784CB66DEB5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{75E66E21-E169-4504-89FA-4784CB66DEB5} = {424CFC36-D6F7-4DBB-BD1C-0C84FE30E665}
EndGlobalSection
EndGlobal
Empty file added examples/Respawn/src/.gitkeep
Empty file.
30 changes: 30 additions & 0 deletions examples/Respawn/tests/Respawn.Tests/DbFixture.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
namespace Respawn.Tests;

[UsedImplicitly]
public sealed class DbFixture : IAsyncLifetime
{
private readonly IContainer _postgreSqlContainer;

public DbFixture()
{
// Testcontainers starts the dependent database (PostgreSQL) and copies the SQL scripts
// to the container before it starts. The PostgreSQL container runs the scripts
// automatically during startup, creating the database schema.
_postgreSqlContainer = new PostgreSqlBuilder()
.WithImage("postgres:15-alpine")
.WithResourceMapping("migrate/", "/docker-entrypoint-initdb.d/")
.Build();
}

public DbConnection DbConnection => new NpgsqlConnection(((PostgreSqlContainer)_postgreSqlContainer).GetConnectionString());

public Task InitializeAsync()
{
return _postgreSqlContainer.StartAsync();
}

public Task DisposeAsync()
{
return _postgreSqlContainer.DisposeAsync().AsTask();
}
}
17 changes: 17 additions & 0 deletions examples/Respawn/tests/Respawn.Tests/Respawn.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net8.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="JetBrains.Annotations" VersionOverride="2023.3.0" PrivateAssets="All"/>
<PackageReference Include="Microsoft.NET.Test.Sdk"/>
<PackageReference Include="Testcontainers.PostgreSql"/>
<PackageReference Include="xunit.runner.visualstudio"/>
<PackageReference Include="xunit"/>
<PackageReference Include="Npgsql"/>
<PackageReference Include="Respawn"/>
</ItemGroup>
<ItemGroup>
<None Include="migrate/*.sql" CopyToOutputDirectory="PreserveNewest"/>
</ItemGroup>
</Project>
60 changes: 60 additions & 0 deletions examples/Respawn/tests/Respawn.Tests/RespawnTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
namespace Respawn.Tests;

public sealed class RespawnTest : IClassFixture<DbFixture>, IDisposable
{
private readonly DbConnection _dbConnection;

public RespawnTest(DbFixture db)
{
_dbConnection = db.DbConnection;
_dbConnection.Open();
}

public void Dispose()
{
_dbConnection.Dispose();
}

[Theory]
[InlineData("jane_doe", "[email protected]", 30)]
[InlineData("john_doe", "[email protected]", 30)]
public async Task UsersTableContainsOneUser(string username, string email, int age)
{
// Respawn resets the database and cleans its state. This allows tests to run without
// interfering with each other. Instead of deleting data at the end of a test, rolling
// back a transaction, or creating a new container instance, Respawn resets the database
// to a clean, empty state by intelligently deleting data from tables.
var respawnerOptions = new RespawnerOptions { DbAdapter = DbAdapter.Postgres };
var respawner = await Respawner.CreateAsync(_dbConnection, respawnerOptions);
await respawner.ResetAsync(_dbConnection);

// This test runs twice and inserts a record into the `users` table for each run.
// The test counts the number of users and expects it to always be 1. If the database
// state is not clean, the assertion fails.
using var insertCommand = _dbConnection.CreateCommand();

var dbParamUsername = insertCommand.CreateParameter();
dbParamUsername.ParameterName = "@username";
dbParamUsername.Value = username;

var dbParamEmail = insertCommand.CreateParameter();
dbParamEmail.ParameterName = "@email";
dbParamEmail.Value = email;

var dbParamAge = insertCommand.CreateParameter();
dbParamAge.ParameterName = "@age";
dbParamAge.Value = age;

insertCommand.CommandText = "INSERT INTO users (username, email, age) VALUES (@username, @email, @age)";
insertCommand.Parameters.Add(dbParamUsername);
insertCommand.Parameters.Add(dbParamEmail);
insertCommand.Parameters.Add(dbParamAge);
insertCommand.ExecuteNonQuery();

using var selectCommand = _dbConnection.CreateCommand();
selectCommand.CommandText = "SELECT COUNT(*) FROM users";
var userCount = Convert.ToInt32(selectCommand.ExecuteScalar());

Assert.Equal(1, userCount);
}
}
9 changes: 9 additions & 0 deletions examples/Respawn/tests/Respawn.Tests/Usings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
global using System;
global using System.Collections.Generic;
global using System.Data.Common;
global using System.Threading.Tasks;
global using DotNet.Testcontainers.Containers;
global using JetBrains.Annotations;
global using Npgsql;
global using Testcontainers.PostgreSql;
global using Xunit;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CREATE TABLE users
(
id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE users ADD COLUMN age INT;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-- INSERT INTO users (username, email, age) VALUES ('john_doe', '[email protected]', 30);

0 comments on commit aa8234d

Please sign in to comment.