{"id":95003,"date":"2023-09-07T08:29:16","date_gmt":"2023-09-07T06:29:16","guid":{"rendered":"https:\/\/code-maze.com\/?p=95003"},"modified":"2024-11-14T16:06:05","modified_gmt":"2024-11-14T15:06:05","slug":"csharp-testing-using-testcontainers-for-net-and-docker","status":"publish","type":"post","link":"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/","title":{"rendered":"Testing Using Testcontainers for .NET and Docker"},"content":{"rendered":"<p>\u00a0In this article, we&#8217;ll explore how to use the Testcontainers library for testing .NET applications using Docker.<\/p>\n<div style=\"padding: 20px; border-left: 5px #dc2323 solid; display: block; margin-bottom: 20px; box-shadow: 1px 1px 5px 0px lightgrey;\">To download the source code for this article, you can visit our <a href=\"https:\/\/github.com\/CodeMazeBlog\/CodeMazeGuides\/tree\/main\/dotnet-client-libraries\/TestcontainersForDotNetAndDocker\" target=\"_blank\" rel=\"nofollow noopener\">GitHub repository<\/a>.<\/div>\n<p>Let&#8217;s get started!<\/p>\n<h2>Understanding Testcontainers<\/h2>\n<p>Testcontainers is an <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-dotnet\" target=\"_blank\" rel=\"nofollow noopener\">open-source library<\/a> that provides a simple and efficient way to manage containers for testing purposes. It does this by utilizing Docker containers across all compatible versions of .NET.<\/p>\n<p>Heavily based on the .NET Docker remote API, this library offers a streamlined implementation, enabling an elegant and adaptable testing environment under any scenario. With it, we can configure, create and delete Docker resources. It prepares and initializes our tests and disposes of everything after they are finished. \u00a0To be able to use Testcontainers in our tests, we need to have Docker installed.<\/p>\n<h2>Setting Up the Environment For Testing<\/h2>\n<p>There are a couple of things we need before we can start testing:<\/p>\n<h3>Creating a .NET Project for Testing<\/h3>\n<p>First, we need a project to test. For this article, we will use a simple CRUD API that deals with cats:<\/p>\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/TestcontainersForDotNetAndDocker.png\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-95004\" src=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/TestcontainersForDotNetAndDocker.png\" alt=\"Solution explorer showing the implementation of our test suite for Testcontainers\" width=\"293\" height=\"382\" srcset=\"https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/TestcontainersForDotNetAndDocker.png 293w, https:\/\/code-maze.com\/wp-content\/uploads\/2023\/08\/TestcontainersForDotNetAndDocker-230x300.png 230w\" sizes=\"auto, (max-width: 293px) 100vw, 293px\" \/><\/a><\/p>\n<p>We have a single <code>Cat<\/code> entity with some basic properties. We also have a <code>DbContext<\/code> with one <code>DbSet&lt;T&gt;<\/code> representing our cats which is implemented by the\u00a0 <code>ApplicationDbContext<\/code> class. Right next to it, we can find the <code>CatRepository<\/code> and <code>CatService<\/code> implementing the CRUD functionality.<\/p>\n<p>Next, we can find the <code>CatController<\/code> which hosts our user interactions. It has five endpoints for creating, retrieving, updating, and deleting cats from our database. We also inject an instance of our <code>ICatService<\/code> implementation and use it as a mediator between the controller and the database.\u00a0<\/p>\n<p>All files mentioned here are part of the GitHub repository for this article.<\/p>\n<p>After this, we can create our test project and proceed with the installation of Testcontainers.<\/p>\n<h3>Installing Testcontainers<\/h3>\n<p>Next, we need to install two NuGet packages &#8211; the main Testcontainers package and one dedicated to an extension for Microsoft SQL Server container:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\">dotnet add package Testcontainers\r\ndotnet add package Testcontainers.MsSql<\/pre>\n<p>Once this is done, we can start utilizing it in our tests.<\/p>\n<h2>Writing Tests With Testcontainers<\/h2>\n<p>Before we can use our test containers, we need to set some things up:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public class CatsApiApplicationFactory : WebApplicationFactory&lt;Program&gt;\r\n{\r\n    private const string Database = \"master\";\r\n    private const string Username = \"sa\";\r\n    private const string Password = \"yourStrong(!)Password\";\r\n    private const ushort MsSqlPort = 1433;\r\n\r\n    private readonly IContainer _mssqlContainer;\r\n}<\/pre>\n<p>First, we create a <code>CatsApiApplicationFactory<\/code>\u00a0class that implements the <code>WebApplicationFactory&lt;T&gt;<\/code> class where <code>T<\/code> is our <code>Program<\/code> class. The <code>WebApplicationFactory&lt;T&gt;<\/code> provides us with functionality for running an application in memory for various testing purposes.<\/p>\n<p>We declare several constants that we will later use for the container&#8217;s configuration and the database connection string, as well as an instance of <code>IContainer<\/code> called <code>_mssqlContainer<\/code>.<\/p>\n<h3>Configuring Default Test Containers<\/h3>\n<p>Next, in the same class, we create a constructor for our <code>CatsApiApplicationFactory<\/code> class:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public CatsApiApplicationFactory()\r\n{\r\n    _mssqlContainer = new MsSqlBuilder().Build();\r\n}<\/pre>\n<p>Here, we create a new instance on the <code>MsSqlBuilder<\/code> class and invoke its <code>Build()<\/code> method. This will create a default MSSQL Docker container for us.<\/p>\n<p>The database name, username, password, and port will be the default ones for the Microsoft SQL Server and the same as the constants we defined earlier. The pre-defined image is <em>mcr.microsoft.com\/mssql\/server:2019-CU18-ubuntu-20.04<\/em>. This approach comes in handy when we just need a SQL Server container and are not interested in the details of setting it up further.<\/p>\n<p>Similar additional NuGet packages offer support for default containers for MySQL, PostgreSQL, MongoDB, Redis, and many others, which you can find in the <a href=\"https:\/\/github.com\/testcontainers\/testcontainers-dotnet\/tree\/develop\" target=\"_blank\" rel=\"nofollow noopener\">GitHub repository from Testcontainers<\/a>.<\/p>\n<h3>Configuring Custom Test Containers<\/h3>\n<p>If we want more control, we can define a custom container:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">public CatsApiApplicationFactory()\r\n{\r\n    _mssqlContainer = new ContainerBuilder()\r\n        .WithImage(\"mcr.microsoft.com\/mssql\/server:2022-latest\")\r\n        .WithPortBinding(MsSqlPort)\r\n        .WithEnvironment(\"ACCEPT_EULA\", \"Y\")\r\n        .WithEnvironment(\"SQLCMDUSER\", Username)\r\n        .WithEnvironment(\"SQLCMDPASSWORD\", Password)\r\n        .WithEnvironment(\"MSSQL_SA_PASSWORD\", Password)\r\n        .Build();\r\n}<\/pre>\n<p>In the constructor, we instantiate our <code>_mssqlContainer<\/code> member variable. We achieve that by using the Testcontainers&#8217; <code>ContainerBuilder<\/code> class and its provided functionality to build container definitions.<\/p>\n<p>We start by using the <code>WithImage()<\/code> method to specify which Docker image we want to use, opting for the latest version of the Microsoft SQL Server 2022.<\/p>\n<p>Then, we move on to the <code>WithPortBinding()<\/code> method, passing the <code>MsSqlPort<\/code> constant to specify which port to use. This will do a one-to-one port mapping from host to container.<\/p>\n<p>Then we chain several instances of the <code>WithEnvironment()<\/code> method to set environment variables on the container. Those variables correspond to important properties such as SQL Server username and password. We finish things off with the <code>Build()<\/code> method which builds an instance of the <code>IContainer<\/code> interface with all of our custom settings.<\/p>\n<h3>Overriding the Database Configuration<\/h3>\n<p>Then, we override the <code>ConfigureWebHost()<\/code> method:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\">protected override void ConfigureWebHost(IWebHostBuilder builder)\r\n{\r\n    var host = _mssqlContainer.Hostname;\r\n    var port = _mssqlContainer.GetMappedPublicPort(MsSqlPort);\r\n\r\n    builder.ConfigureServices(services =&gt;\r\n    {\r\n        services.RemoveAll(typeof(DbContextOptions&lt;ApplicationDbContext&gt;));\r\n\r\n        services.AddDbContext&lt;ApplicationDbContext&gt;(options =&gt;\r\n            options.UseSqlServer(\r\n                $\"Server={host},{port};Database={Database};User Id={Username};Password={Password};TrustServerCertificate=True\"));\r\n    });\r\n}<\/pre>\n<p>The first thing we do is extract the <code>host<\/code> and <code>port<\/code> of the container.<\/p>\n<p>Then, in the <code>ConfigureServices()<\/code> method we first remove all services of type <code>DbContextOptions&lt;ApplicationDbContext&gt;<\/code> to make sure we clear all database configurations. Then we add our <code>ApplicationDbContext<\/code> again using the <code>AddDbContext()<\/code> method and passing a connection string pointing to our container.<\/p>\n<h3>Starting and Stopping Containers<\/h3>\n<p>Finally, let&#8217;s add a way to start our container before each test and stop it afterward:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-highlight=\"1,3-6,8-11\">public class CatsApiApplicationFactory: WebApplicationFactory&lt;Program&gt;, IAsyncLifetime\r\n{\r\n    public async Task InitializeAsync()\r\n    {\r\n        await _mssqlContainer.StartAsync();\r\n    }\r\n    \r\n    public new async Task DisposeAsync()\r\n    {\r\n        await _mssqlContainer.DisposeAsync();\r\n    }\r\n}<\/pre>\n<p>We implement the xUnit&#8217;s interface <code>IAsyncLifetime<\/code> and define its methods to achieve this. In the <code>InitializeAsync()<\/code> method we the <code>StartAsync()<\/code> method to start our container. In the <code>DisposeAsync()<\/code> method, we dispose of our container using the identically named disposing method.<\/p>\n<p>Now we can easily write our tests:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-highlight=\"7\">public class CreateCatEndpointTests : IClassFixture&lt;CatsApiApplicationFactory&gt;\r\n{\r\n    private readonly HttpClient _httpClient;\r\n\r\n    public CreateCatEndpointTests(CatsApiApplicationFactory catsApiApplicationFactory)\r\n    {\r\n        _httpClient = catsApiApplicationFactory.CreateClient();\r\n    }\r\n\r\n    [Fact]\r\n    public async Task GivenCatDoesNotExist_WhenCreateCatEndpointIsInvoked_ThenCreatedIsReturned()\r\n    {\r\n        \/\/ Arrange\r\n        var catRequest = new CreateCatRequest(\"Tombili\", 6, 7);\r\n\r\n        \/\/ Act\r\n        var response = await _httpClient.PostAsJsonAsync(\"CreateCat\", catRequest);\r\n\r\n        \/\/ Assert\r\n        var catResponse = await response.Content.ReadFromJsonAsync&lt;CatResponse&gt;();\r\n        catResponse.Should().NotBeNull().And.BeEquivalentTo(catRequest);\r\n        response.StatusCode.Should().Be(HttpStatusCode.Created);\r\n        response.Headers.Location.Should().Be($\"http:\/\/localhost\/GetCat\/{catResponse.Id}\");\r\n    }\r\n}<\/pre>\n<p>We create the <code>CreateCatEndpointTests<\/code> class that implements <code>IClassFixture&lt;CatsApiApplicationFactory&gt;<\/code>.<\/p>\n<p>In the constructor, we initialize a <code>HttpClient<\/code> using the <code>CatsApiApplicationFactory<\/code>&#8216;s <code>CreateClient()<\/code> method. With this approach, xUnit enables us to create a new API with its own containerized database for each separate test class. We then use the client to call our API in the test methods.\u00a0\u00a0<\/p>\n<p>You can find a lot more test cases in our <a href=\"https:\/\/github.com\/CodeMazeBlog\/CodeMazeGuides\/tree\/main\/dotnet-client-libraries\/TestcontainersForDotNetAndDocker\/TestcontainersForDotNetAndDocker.Tests\" target=\"_blank\" rel=\"nofollow noopener\">source code repository<\/a>.<\/p>\n<h2>Best Practices for Tests With Testcontainers<\/h2>\n<p>Let&#8217;s see what we can do to take full advantage of Testcontainers in our testing workflows:<\/p>\n<h3>Wait Strategies<\/h3>\n<p>Awaiting strategies are a key feature that ensures no tests will be run until the Docker container is up and running:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-highlight=\"10\">public CatsApiApplicationFactory()\r\n{\r\n    _mssqlContainer = new ContainerBuilder()\r\n        .WithImage(\"mcr.microsoft.com\/mssql\/server:2022-latest\")\r\n        .WithPortBinding(MsSqlPort)\r\n        .WithEnvironment(\"ACCEPT_EULA\", \"Y\")\r\n        .WithEnvironment(\"SQLCMDUSER\", Username)\r\n        .WithEnvironment(\"SQLCMDPASSWORD\", Password)\r\n        .WithEnvironment(\"MSSQL_SA_PASSWORD\", Password)\r\n        .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(MsSqlPort))\r\n        .Build();\r\n}<\/pre>\n<p>In our container initialization, we add the <code>WithWaitStrategy()<\/code> method. It takes one parameter of the custom <code>IWaitForContainerOS<\/code> interface.<\/p>\n<p>For this, we use the <code>Wait<\/code> class with two of its methods. We start with the <code>ForUnixContainer()<\/code> method and follow up with the <code>UntilPortIsAvailable()<\/code> method passing the <code>MsSqlPort<\/code>. This prevents our test methods from running before everything is up and running, saving us from failed tests due to the unready containers.<\/p>\n<h3>Random Host Ports<\/h3>\n<p>Having a static host port is not ideal as it can lead to clashes, so it is better to use dynamic host ports:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"csharp\" data-enlighter-highlight=\"5\">public CatsApiApplicationFactory()\r\n{\r\n    _mssqlContainer = new ContainerBuilder()\r\n        .WithImage(\"mcr.microsoft.com\/mssql\/server:2022-latest\")\r\n        .WithPortBinding(MsSqlPort, true)\r\n        .WithEnvironment(\"ACCEPT_EULA\", \"Y\")\r\n        .WithEnvironment(\"SQLCMDUSER\", Username)\r\n        .WithEnvironment(\"SQLCMDPASSWORD\", Password)\r\n        .WithEnvironment(\"MSSQL_SA_PASSWORD\", Password)\r\n        .WithWaitStrategy(Wait.ForUnixContainer().UntilPortIsAvailable(MsSqlPort))\r\n        .Build();\r\n}<\/pre>\n<p>Again in our <code>CatsApiApplicationFactory<\/code> constructor, we update the <code>WithPortBinding()<\/code> method call by passing <code>true<\/code> as a second parameter. This will assign a random host port for each instance of our container.<\/p>\n<h2>Conclusion<\/h2>\n<p>In this article, we delved into the potential of the Testcontainers library for enhancing the efficacy of testing .NET applications using Docker. With it, creating database containers for our tests is relatively easy, coming down to a few lines of code.<\/p>\n<p>Moreover, the Testcontainers package goes beyond mere containerization. It aids in provisioning the necessary infrastructure within the test itself and simplifies access to vital resources. Instead of external provisioning in a separate CI\/CD pipeline, with the complexities of resource sharing, Testcontainers streamlines the process by integrating the container directly into the test, making access very straightforward.<\/p>\n<p>As the software development landscape demands more robust testing methodologies, Testcontainers provides us with a powerful tool for testing excellence through containerization.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u00a0In this article, we&#8217;ll explore how to use the Testcontainers library for testing .NET applications using Docker. Let&#8217;s get started! Understanding Testcontainers Testcontainers is an open-source library that provides a simple and efficient way to manage containers for testing purposes. It does this by utilizing Docker containers across all compatible versions of .NET. Heavily based [&hellip;]<\/p>\n","protected":false},"author":6,"featured_media":62189,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"categories":[1112],"tags":[1811,577,1948,576],"class_list":["post-95003","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-testing","tag-c","tag-integration-testing","tag-testcontainers","tag-testing","et-has-post-format-content","et_post_format-et-post-format-standard"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.7 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Testing Using Testcontainers for .NET and Docker - Code Maze<\/title>\n<meta name=\"description\" content=\"\u00a0In this article, we&#039;ll explore how Testcontainers can be leveraged for testing .NET applications using Docker.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Testing Using Testcontainers for .NET and Docker - Code Maze\" \/>\n<meta property=\"og:description\" content=\"\u00a0In this article, we&#039;ll explore how Testcontainers can be leveraged for testing .NET applications using Docker.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/\" \/>\n<meta property=\"og:site_name\" content=\"Code Maze\" \/>\n<meta property=\"article:published_time\" content=\"2023-09-07T06:29:16+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-11-14T15:06:05+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-csharp.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1100\" \/>\n\t<meta property=\"og:image:height\" content=\"620\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Code Maze\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/CodeMazeBlog\" \/>\n<meta name=\"twitter:site\" content=\"@CodeMazeBlog\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Code Maze\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":[\"Article\",\"BlogPosting\"],\"@id\":\"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/\"},\"author\":{\"name\":\"Code Maze\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/09d29b223012c8e94a68ba62861d0b04\"},\"headline\":\"Testing Using Testcontainers for .NET and Docker\",\"datePublished\":\"2023-09-07T06:29:16+00:00\",\"dateModified\":\"2024-11-14T15:06:05+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/\"},\"wordCount\":1140,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/code-maze.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-csharp.png\",\"keywords\":[\"C#\",\"Integration Testing\",\"Testcontainers\",\"Testing\"],\"articleSection\":[\"Testing\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/\",\"url\":\"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/\",\"name\":\"Testing Using Testcontainers for .NET and Docker - Code Maze\",\"isPartOf\":{\"@id\":\"https:\/\/code-maze.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-csharp.png\",\"datePublished\":\"2023-09-07T06:29:16+00:00\",\"dateModified\":\"2024-11-14T15:06:05+00:00\",\"description\":\"\u00a0In this article, we'll explore how Testcontainers can be leveraged for testing .NET applications using Docker.\",\"breadcrumb\":{\"@id\":\"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/#primaryimage\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-csharp.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-csharp.png\",\"width\":1100,\"height\":620,\"caption\":\"C# Development\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/code-maze.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Testing Using Testcontainers for .NET and Docker\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/code-maze.com\/#website\",\"url\":\"https:\/\/code-maze.com\/\",\"name\":\"Code Maze\",\"description\":\"Learn. Code. Succeed.\",\"publisher\":{\"@id\":\"https:\/\/code-maze.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/code-maze.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/code-maze.com\/#organization\",\"name\":\"Code Maze\",\"url\":\"https:\/\/code-maze.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png\",\"width\":3511,\"height\":3510,\"caption\":\"Code Maze\"},\"image\":{\"@id\":\"https:\/\/code-maze.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/x.com\/CodeMazeBlog\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/09d29b223012c8e94a68ba62861d0b04\",\"name\":\"Code Maze\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/code-maze.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez-150x150.png\",\"contentUrl\":\"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez-150x150.png\",\"caption\":\"Code Maze\"},\"description\":\"This is the standard author on the site. Most articles are published by individual authors, with their profiles, but when several authors have contributed, we publish collectively as a part of this profile.\",\"sameAs\":[\"https:\/\/www.linkedin.com\/company\/codemaze\/\",\"https:\/\/x.com\/https:\/\/twitter.com\/CodeMazeBlog\"],\"url\":\"https:\/\/code-maze.com\/author\/codemazecontributor\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Testing Using Testcontainers for .NET and Docker - Code Maze","description":"\u00a0In this article, we'll explore how Testcontainers can be leveraged for testing .NET applications using Docker.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/","og_locale":"en_US","og_type":"article","og_title":"Testing Using Testcontainers for .NET and Docker - Code Maze","og_description":"\u00a0In this article, we'll explore how Testcontainers can be leveraged for testing .NET applications using Docker.","og_url":"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/","og_site_name":"Code Maze","article_published_time":"2023-09-07T06:29:16+00:00","article_modified_time":"2024-11-14T15:06:05+00:00","og_image":[{"width":1100,"height":620,"url":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-csharp.png","type":"image\/png"}],"author":"Code Maze","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/CodeMazeBlog","twitter_site":"@CodeMazeBlog","twitter_misc":{"Written by":"Code Maze","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":["Article","BlogPosting"],"@id":"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/#article","isPartOf":{"@id":"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/"},"author":{"name":"Code Maze","@id":"https:\/\/code-maze.com\/#\/schema\/person\/09d29b223012c8e94a68ba62861d0b04"},"headline":"Testing Using Testcontainers for .NET and Docker","datePublished":"2023-09-07T06:29:16+00:00","dateModified":"2024-11-14T15:06:05+00:00","mainEntityOfPage":{"@id":"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/"},"wordCount":1140,"commentCount":0,"publisher":{"@id":"https:\/\/code-maze.com\/#organization"},"image":{"@id":"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/#primaryimage"},"thumbnailUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-csharp.png","keywords":["C#","Integration Testing","Testcontainers","Testing"],"articleSection":["Testing"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/","url":"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/","name":"Testing Using Testcontainers for .NET and Docker - Code Maze","isPartOf":{"@id":"https:\/\/code-maze.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/#primaryimage"},"image":{"@id":"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/#primaryimage"},"thumbnailUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-csharp.png","datePublished":"2023-09-07T06:29:16+00:00","dateModified":"2024-11-14T15:06:05+00:00","description":"\u00a0In this article, we'll explore how Testcontainers can be leveraged for testing .NET applications using Docker.","breadcrumb":{"@id":"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/#primaryimage","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-csharp.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2021\/12\/social-csharp.png","width":1100,"height":620,"caption":"C# Development"},{"@type":"BreadcrumbList","@id":"https:\/\/code-maze.com\/csharp-testing-using-testcontainers-for-net-and-docker\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/code-maze.com\/"},{"@type":"ListItem","position":2,"name":"Testing Using Testcontainers for .NET and Docker"}]},{"@type":"WebSite","@id":"https:\/\/code-maze.com\/#website","url":"https:\/\/code-maze.com\/","name":"Code Maze","description":"Learn. Code. Succeed.","publisher":{"@id":"https:\/\/code-maze.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/code-maze.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/code-maze.com\/#organization","name":"Code Maze","url":"https:\/\/code-maze.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/#\/schema\/logo\/image\/","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez.png","width":3511,"height":3510,"caption":"Code Maze"},"image":{"@id":"https:\/\/code-maze.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/CodeMazeBlog"]},{"@type":"Person","@id":"https:\/\/code-maze.com\/#\/schema\/person\/09d29b223012c8e94a68ba62861d0b04","name":"Code Maze","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/code-maze.com\/#\/schema\/person\/image\/","url":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez-150x150.png","contentUrl":"https:\/\/code-maze.com\/wp-content\/uploads\/2020\/01\/Code-Maze-Only-Logo-Transparent-HRez-150x150.png","caption":"Code Maze"},"description":"This is the standard author on the site. Most articles are published by individual authors, with their profiles, but when several authors have contributed, we publish collectively as a part of this profile.","sameAs":["https:\/\/www.linkedin.com\/company\/codemaze\/","https:\/\/x.com\/https:\/\/twitter.com\/CodeMazeBlog"],"url":"https:\/\/code-maze.com\/author\/codemazecontributor\/"}]}},"_links":{"self":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/95003","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/users\/6"}],"replies":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/comments?post=95003"}],"version-history":[{"count":10,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/95003\/revisions"}],"predecessor-version":[{"id":123683,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/posts\/95003\/revisions\/123683"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/media\/62189"}],"wp:attachment":[{"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/media?parent=95003"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/categories?post=95003"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/code-maze.com\/wp-json\/wp\/v2\/tags?post=95003"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}