{"id":21464,"date":"2023-04-03T13:47:09","date_gmt":"2023-04-03T06:47:09","guid":{"rendered":"https:\/\/huongdanjava.com\/?p=21464"},"modified":"2026-02-15T07:01:05","modified_gmt":"2026-02-15T00:01:05","slug":"gioi-thieu-ve-testcontainers","status":"publish","type":"post","link":"https:\/\/huongdanjava.com\/vi\/gioi-thieu-ve-testcontainers.html","title":{"rendered":"Gi\u1edbi thi\u1ec7u v\u1ec1 Testcontainers"},"content":{"rendered":"<p><a href=\"https:\/\/www.testcontainers.org\/\" target=\"_blank\" rel=\"noopener\">Testcontainers<\/a> l\u00e0 m\u1ed9t th\u01b0 vi\u1ec7n gi\u00fap ch\u00fang ta c\u00f3 th\u1ec3 vi\u1ebft unit test cho c\u00e1c \u1ee9ng d\u1ee5ng, database ch\u1ea1y tr\u00ean m\u1ed9t Docker container. Testcontainers s\u1ebd gi\u00fap ch\u00fang ta ch\u1ea1y c\u00e1c \u1ee9ng d\u1ee5ng ho\u1eb7c database l\u00ean s\u1eed d\u1ee5ng c\u00e1c Docker Images, sau \u0111\u00f3 th\u00ec ch\u00fang ta s\u1ebd s\u1eed d\u1ee5ng c\u00e1c plugin m\u00e0 n\u00f3 h\u1ed7 tr\u1ee3 \u0111\u1ec3 implement code unit test theo \u00fd m\u00ecnh mu\u1ed1n. Testcontrainers h\u1ed7 tr\u1ee3 cho nhi\u1ec1u ng\u00f4n ng\u1eef kh\u00e1c nhau, ngo\u00e0i Java, n\u00f3 c\u00f2n c\u00f3 phi\u00ean b\u1ea3n d\u00e0nh cho Go, .Net, Node.js, Python, Rust, Haskell. Trong b\u00e0i vi\u1ebft n\u00e0y, m\u00ecnh s\u1ebd h\u01b0\u1edbng d\u1eabn c\u00e1c b\u1ea1n l\u00e0m th\u1ebf n\u00e0o \u0111\u1ec3 s\u1eed d\u1ee5ng Testcontainers cho Java \u0111\u1ec3 vi\u1ebft unit test cho ph\u1ea7n thao t\u00e1c v\u1edbi MySQL database c\u1ee7a m\u1ed9t \u1ee9ng d\u1ee5ng Java \u0111\u01a1n gi\u1ea3n c\u00e1c b\u1ea1n nh\u00e9!<\/p>\n<p>\u0110\u1ea7u ti\u00ean, m\u00ecnh s\u1ebd t\u1ea1o m\u1edbi m\u1ed9t Maven project \u0111\u1ec3 l\u00e0m v\u00ed d\u1ee5:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-21573 aligncenter\" src=\"https:\/\/huongdanjava.com\/wp-content\/uploads\/2023\/04\/gioi-thieu-ve-testcontainers-1.png\" alt=\"\" width=\"700\" height=\"461\" \/><\/p>\n<p>M\u00ecnh s\u1ebd khai b\u00e1o Testcontainers v\u1edbi dependency management, JUnit Jupiter v\u00e0 MySQL JDBC driver dependency cho project n\u00e0y nh\u01b0 sau:<\/p>\n<pre class=\"lang:xhtml decode:true \">&lt;dependencyManagement&gt;\r\n  &lt;dependencies&gt;\r\n    &lt;dependency&gt;\r\n      &lt;groupId&gt;org.testcontainers&lt;\/groupId&gt;\r\n      &lt;artifactId&gt;testcontainers-bom&lt;\/artifactId&gt;\r\n      &lt;version&gt;${testcontainers.version}&lt;\/version&gt;\r\n      &lt;type&gt;pom&lt;\/type&gt;\r\n      &lt;scope&gt;import&lt;\/scope&gt;\r\n    &lt;\/dependency&gt;\r\n  &lt;\/dependencies&gt;\r\n&lt;\/dependencyManagement&gt;\r\n\r\n&lt;dependencies&gt;\r\n  &lt;dependency&gt;\r\n    &lt;groupId&gt;com.mysql&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;mysql-connector-j&lt;\/artifactId&gt;\r\n    &lt;version&gt;${mysql-connector-j.version}&lt;\/version&gt;\r\n  &lt;\/dependency&gt;\r\n\r\n  &lt;dependency&gt;\r\n    &lt;groupId&gt;org.testcontainers&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;testcontainers&lt;\/artifactId&gt;\r\n    &lt;scope&gt;test&lt;\/scope&gt;\r\n  &lt;\/dependency&gt;\r\n  &lt;dependency&gt;\r\n    &lt;groupId&gt;org.testcontainers&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;testcontainers-junit-jupiter&lt;\/artifactId&gt;\r\n    &lt;scope&gt;test&lt;\/scope&gt;\r\n  &lt;\/dependency&gt;\r\n  &lt;dependency&gt;\r\n    &lt;groupId&gt;org.testcontainers&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;testcontainers-mysql&lt;\/artifactId&gt;\r\n    &lt;scope&gt;test&lt;\/scope&gt;\r\n  &lt;\/dependency&gt;\r\n\r\n  &lt;dependency&gt;\r\n    &lt;groupId&gt;org.junit.jupiter&lt;\/groupId&gt;\r\n    &lt;artifactId&gt;junit-jupiter&lt;\/artifactId&gt;\r\n    &lt;version&gt;${junit-jupiter.version}&lt;\/version&gt;\r\n    &lt;scope&gt;test&lt;\/scope&gt;\r\n  &lt;\/dependency&gt;\r\n&lt;\/dependencies&gt;<\/pre>\n<p>v\u1edbi:<\/p>\n<pre class=\"lang:xhtml decode:true \">&lt;properties&gt;\r\n  &lt;maven.compiler.source&gt;25&lt;\/maven.compiler.source&gt;\r\n  &lt;maven.compiler.target&gt;25&lt;\/maven.compiler.target&gt;\r\n  &lt;project.build.sourceEncoding&gt;UTF-8&lt;\/project.build.sourceEncoding&gt;\r\n\r\n  &lt;testcontainers.version&gt;2.0.3&lt;\/testcontainers.version&gt;\r\n  &lt;mysql-connector-j.version&gt;9.6.0&lt;\/mysql-connector-j.version&gt;\r\n  &lt;junit-jupiter.version&gt;6.0.2&lt;\/junit-jupiter.version&gt;\r\n&lt;\/properties&gt;<\/pre>\n<p>\u0110\u1ec3 l\u00e0m v\u00ed d\u1ee5, m\u00ecnh s\u1ebd \u0111\u1ecbnh ngh\u0129a m\u1ed9t table student trong MySQL database v\u1edbi c\u1ea5u tr\u00fac \u0111\u01a1n gi\u1ea3n nh\u01b0 sau:<\/p>\n<pre class=\"lang:mysql decode:true \">CREATE TABLE `students` (\r\n  `id` int(11) NOT NULL AUTO_INCREMENT,\r\n  `name` varchar(45) NOT NULL,\r\n  PRIMARY KEY (`id`)\r\n) ENGINE=InnoDB DEFAULT CHARSET=utf8;<\/pre>\n<p>Data trong table student nh\u01b0 sau:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-21575 aligncenter\" src=\"https:\/\/huongdanjava.com\/wp-content\/uploads\/2023\/04\/gioi-thieu-ve-testcontainers-2.png\" alt=\"\" width=\"700\" height=\"291\" \/><\/p>\n<p>\u0110\u1ec3 l\u1ea5y th\u00f4ng tin trong table student n\u00e0y, m\u00ecnh s\u1ebd vi\u1ebft code JDBC nh\u01b0 sau:<\/p>\n<pre class=\"lang:java decode:true\">package com.huongdanjava.testcontainers;\r\n\r\nimport java.sql.Connection;\r\nimport java.sql.ResultSet;\r\nimport java.sql.SQLException;\r\nimport java.sql.Statement;\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\npublic class StudentService {\r\n\r\n  public List&lt;Student&gt; getAllStudents(Connection connection) throws SQLException {\r\n    List&lt;Student&gt; students = new ArrayList&lt;&gt;();\r\n    Statement statement = connection.createStatement();\r\n\r\n    ResultSet rs = statement.executeQuery(\"SELECT * FROM students\");\r\n    while (rs.next()) {\r\n      Student student = new Student(rs.getInt(\"id\"), rs.getString(\"name\"));\r\n      students.add(student);\r\n    }\r\n\r\n    return students;\r\n  }\r\n}\r\n<\/pre>\n<p>v\u1edbi class Student c\u00f3 n\u1ed9i dung nh\u01b0 sau:<\/p>\n<pre class=\"lang:java decode:true \">package com.huongdanjava.testcontainers;\r\n\r\npublic record Student(int id, String name) {\r\n\r\n}\r\n<\/pre>\n<p>Class main \u0111\u1ec3 ch\u1ea1y \u1ee9ng d\u1ee5ng n\u00e0y nh\u01b0 sau:<\/p>\n<pre class=\"lang:java decode:true\">package com.huongdanjava.testcontainers;\r\n\r\nimport java.sql.Connection;\r\nimport java.sql.DriverManager;\r\nimport java.sql.SQLException;\r\nimport java.util.List;\r\n\r\npublic class Application {\r\n\r\n  public static void main(String[] args) throws SQLException {\r\n    Connection connection = DriverManager.getConnection(\"jdbc:mysql:\/\/localhost:3306\/example\",\r\n        \"root\", \"123456\");\r\n    StudentService studentService = new StudentService();\r\n    List&lt;Student&gt; students = studentService.getAllStudents(connection);\r\n\r\n    students.forEach(s -&gt; {\r\n      System.out.println(\"ID: \" + s.id() + \", name: \" + s.name());\r\n    });\r\n  }\r\n\r\n}\r\n<\/pre>\n<p>K\u1ebft qu\u1ea3:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-21576 aligncenter\" src=\"https:\/\/huongdanjava.com\/wp-content\/uploads\/2023\/04\/gioi-thieu-ve-testcontainers-3.png\" alt=\"\" width=\"700\" height=\"422\" \/><\/p>\n<p>\u0110\u1ec3 vi\u1ebft unit test cho ph\u01b0\u01a1ng th\u1ee9c getAllStudents() l\u1ea5y th\u00f4ng tin sinh vi\u00ean t\u1eeb database, ng\u00e0y x\u01b0a, c\u00e1c b\u1ea1n c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng H2 in-memory database. V\u1edbi \u001dapproach n\u00e0y, code unit test c\u1ee7a ch\u00fang ta kh\u00f4ng th\u1ef1c s\u1ef1 ch\u1ea1y v\u1edbi database m\u00e0 ch\u00fang ta \u0111ang s\u1eed d\u1ee5ng cho \u1ee9ng d\u1ee5ng. V\u00e0 do \u0111\u00f3, ch\u00fang ta c\u00f3 th\u1ec3 g\u1eb7p c\u00e1c issue khi ch\u1ea1y \u1ee9ng d\u1ee5ng m\u00e0 code unit test kh\u00f4ng detect \u0111\u01b0\u1ee3c.<\/p>\n<p>Gi\u1edd c\u00e1c b\u1ea1n c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng Testcontainers \u0111\u1ec3 gi\u1ea3i quy\u1ebft b\u1ea5t c\u1eadp n\u00e0y. Testcontainer s\u1ebd gi\u00fap ch\u00fang ta ch\u1ea1y code unit test v\u1edbi database th\u1ef1c s\u1ef1 m\u00e0 \u1ee9ng d\u1ee5ng ch\u00fang ta \u0111ang s\u1eed d\u1ee5ng lu\u00f4n.<\/p>\n<p><strong>\u0110i\u1ec3m b\u1ea5t ti\u1ec7n c\u1ee7a gi\u1ea3i ph\u00e1p n\u00e0y l\u00e0 c\u00e1c b\u1ea1n ph\u1ea3i c\u00f3 Docker \u0111\u01b0\u1ee3c c\u00e0i \u0111\u1eb7t tr\u00ean m\u00e1y ch\u1ea1y unit test<\/strong>, th\u1ebf nh\u01b0ng \u0111i\u1ec3m b\u1ea5t ti\u1ec7n n\u00e0y kh\u00f4ng ph\u1ea3i l\u00e0 v\u1ea5n \u0111\u1ec1 l\u1edbn ph\u1ea3i kh\u00f4ng c\u00e1c b\u1ea1n?<\/p>\n<p>\u0110\u1ec3 vi\u1ebft unit test cho class StudentService s\u1eed d\u1ee5ng Testcontainers, m\u00ecnh s\u1ebd t\u1ea1o m\u1edbi m\u1ed9t class v\u00e0 annotate class n\u00e0y v\u1edbi annotation @Testcontainers c\u1ee7a Testcontainer nh\u01b0 sau:<\/p>\n<pre class=\"lang:java decode:true\">package com.huongdanjava.testcontainers;\r\n\r\nimport org.testcontainers.junit.jupiter.Testcontainers;\r\n\r\n@Testcontainers\r\npublic class StudentServiceTest {\r\n\r\n}\r\n<\/pre>\n<p>Annotation @Testcontainers n\u00e0y c\u00f3 m\u1ed9t thu\u1ed9c t\u00ednh l\u00e0 disabledWithoutDocker gi\u00fap cho code unit test v\u1edbi Testcontainers c\u1ee7a ch\u00fang ta s\u1ebd t\u1ef1 \u0111\u1ed9ng disable n\u1ebfu m\u00e1y ch\u1ea1y unit test kh\u00f4ng \u0111\u01b0\u1ee3c c\u00e0i \u0111\u1eb7t Docker \u0111\u00f3 c\u00e1c b\u1ea1n! M\u1eb7c \u0111\u1ecbnh gi\u00e1 tr\u1ecb c\u1ee7a thu\u1ed9c t\u00ednh n\u00e0y l\u00e0 false ngh\u0129a l\u00e0 code unit test c\u1ee7a ch\u00fang ta s\u1ebd kh\u00f4ng b\u1ecb disable n\u1ebfu m\u00e1y ch\u1ea1y unit test kh\u00f4ng \u0111\u01b0\u1ee3c c\u00e0i Docker. Tu\u1ef3 ho\u00e0n c\u1ea3nh, c\u00e1c b\u1ea1n c\u00f3 th\u1ec3 th\u00eam thu\u1ed9c t\u00ednh n\u00e0y n\u1ebfu mu\u1ed1n nh\u00e9. M\u00e1y m\u00ecnh \u0111ang c\u00e0i Docker n\u00ean m\u00ecnh ko c\u1ea7n ph\u1ea3i khai b\u00e1o thu\u1ed9c t\u00ednh n\u00e0y.<\/p>\n<p>B\u00e2y gi\u1edd ch\u00fang ta s\u1ebd khai b\u00e1o container m\u00e0 ch\u00fang ta s\u1ebd c\u1ea7n ch\u1ea1y tr\u01b0\u1edbc khi code unit test \u0111\u01b0\u1ee3c execute v\u1edbi annotation @Container. Cho v\u00ed d\u1ee5 c\u1ee7a m\u00ecnh nh\u01b0 sau:<\/p>\n<pre class=\"lang:java decode:true\">@Container\r\npublic static MySQLContainer&lt;?&gt; container = new MySQLContainer&lt;&gt;(\"mysql:latest\")\r\n    .withDatabaseName(\"example\")\r\n    .withPassword(\"123456\")\r\n    .withInitScript(\"db.sql\")\r\n    .withReuse(true);<\/pre>\n<p>M\u1eb7c \u0111\u1ecbnh th\u00ec container c\u1ee7a <a href=\"https:\/\/www.testcontainers.org\/modules\/databases\/mysql\/\" target=\"_blank\" rel=\"noopener\">MySQL v\u1edbi Testcontainer<\/a> s\u1ebd ch\u1ea1y v\u1edbi user &#8220;root&#8221; v\u00e0 password l\u00e0 &#8220;test&#8221;. Cho v\u00ed d\u1ee5 c\u1ee7a m\u00ecnh th\u00ec m\u00ecnh \u0111\u00e3 thay \u0111\u1ed5i password sang &#8220;123456&#8221; nh\u01b0 c\u00e1c b\u1ea1n th\u1ea5y. Database name m\u00ecnh \u0111\u1ec3 l\u00e0 &#8220;example&#8221;.<\/p>\n<p>M\u00ecnh c\u0169ng khai b\u00e1o m\u1ed9t initial SQL script \u0111\u1ec3 khi ch\u1ea1y container l\u00ean, Testcontainers s\u1ebd t\u1ef1 \u0111\u1ed9ng t\u1ea1o m\u1edbi table students v\u00e0 insert data v\u00e0o table n\u00e0y. N\u1ed9i dung c\u1ee7a t\u1eadp tin db.sql n\u1eb1m trong th\u01b0 m\u1ee5c src\/test\/resources nh\u01b0 sau:<\/p>\n<pre class=\"lang:mysql decode:true \">CREATE TABLE `students` (\r\n  `id` int(11) NOT NULL AUTO_INCREMENT,\r\n  `name` varchar(45) NOT NULL,\r\n  PRIMARY KEY (`id`)\r\n) ENGINE=InnoDB DEFAULT CHARSET=utf8;\r\n\r\nINSERT INTO students SET name='Khanh';\r\nINSERT INTO students SET name='Thanh'<\/pre>\n<p>Ph\u01b0\u01a1ng th\u1ee9c withReuse() gi\u00fap ch\u00fang ta c\u00f3 th\u1ec3 s\u1eed d\u1ee5ng l\u1ea1i container m\u00e0 ch\u00fang ta \u0111\u00e3 kh\u1edfi t\u1ea1o tr\u01b0\u1edbc \u0111\u00f3.<\/p>\n<p>\u0110\u1ec3 ch\u1ea1y container m\u00e0 ch\u00fang ta \u0111\u00e3 khai b\u00e1o \u1edf tr\u00ean, c\u00e1c b\u1ea1n c\u00f3 th\u1ec3 g\u1ecdi ph\u01b0\u01a1ng th\u1ee9c start() trong ph\u01b0\u01a1ng th\u1ee9c \u0111\u01b0\u1ee3c annotate v\u1edbi annotation @BeforeAll c\u1ee7a JUnit 5 nh\u01b0 sau:<\/p>\n<pre class=\"lang:java decode:true\">@BeforeAll\r\npublic static void init() throws SQLException {\r\n  container.start();\r\n\r\n  connection = DriverManager.getConnection(container.getJdbcUrl(),\r\n      \"root\", \"123456\");\r\n}<\/pre>\n<p>Nh\u01b0 c\u00e1c b\u1ea1n th\u1ea5y, \u001dm\u00ecnh c\u0169ng \u0111\u00e3 kh\u1edfi t\u1ea1o \u0111\u1ed1i t\u01b0\u1ee3ng \u001dConnection t\u1eeb th\u00f4ng tin c\u1ee7a MySQL container m\u00e0 m\u00ecnh \u0111\u00e3 ch\u1ea1y.<\/p>\n<p>B\u00e2y gi\u1edd, th\u00ec c\u00e1c b\u1ea1n c\u00f3 th\u1ec3 vi\u1ebft unit test cho ph\u01b0\u01a1ng th\u1ee9c getAllStudents() nh\u01b0 sau:<\/p>\n<pre class=\"lang:java decode:true \">@Test\r\npublic void testGetAllStudents() throws SQLException {\r\n  List&lt;Student&gt; allStudents = studentService.getAllStudents(connection);\r\n  Assertions.assertTrue(allStudents.size() == 2);\r\n}<\/pre>\n<p>To\u00e0n b\u1ed9 code unit test c\u1ee7a m\u00ecnh cho class StudentService nh\u01b0 sau:<\/p>\n<pre class=\"lang:java decode:true \">package com.huongdanjava.testcontainers;\r\n\r\nimport java.sql.Connection;\r\nimport java.sql.DriverManager;\r\nimport java.sql.SQLException;\r\nimport java.util.List;\r\nimport org.junit.jupiter.api.Assertions;\r\nimport org.junit.jupiter.api.BeforeAll;\r\nimport org.junit.jupiter.api.Test;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\nimport org.testcontainers.containers.MySQLContainer;\r\nimport org.testcontainers.junit.jupiter.Container;\r\nimport org.testcontainers.junit.jupiter.Testcontainers;\r\n\r\n@Testcontainers\r\npublic class StudentServiceTest {\r\n\r\n  private StudentService studentService = new StudentService();\r\n\r\n  private static Connection connection;\r\n\r\n  @Container\r\n  public static MySQLContainer&lt;?&gt; container = new MySQLContainer&lt;&gt;(\"mysql:latest\")\r\n      .withDatabaseName(\"example\")\r\n      .withPassword(\"123456\")\r\n      .withInitScript(\"db.sql\")\r\n      .withReuse(true);\r\n\r\n  @BeforeAll\r\n  public static void init() throws SQLException {\r\n    container.start();\r\n\r\n    connection = DriverManager.getConnection(container.getJdbcUrl(),\r\n        \"root\", \"123456\");\r\n  }\r\n\r\n  @Test\r\n  public void testGetAllStudents() throws SQLException {\r\n    List&lt;Student&gt; allStudents = studentService.getAllStudents(connection);\r\n    Assertions.assertTrue(allStudents.size() == 2);\r\n  }\r\n}\r\n<\/pre>\n<p>K\u1ebft qu\u1ea3:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-21579 aligncenter\" src=\"https:\/\/huongdanjava.com\/wp-content\/uploads\/2023\/04\/gioi-thieu-ve-testcontainers-4.png\" alt=\"\" width=\"700\" height=\"457\" \/><\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-right kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;right&quot;,&quot;id&quot;:&quot;21464&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;0&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;0&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;4&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;0\\\/5 - (0 votes)&quot;,&quot;size&quot;:&quot;24&quot;,&quot;title&quot;:&quot;Gi\u1edbi thi\u1ec7u v\u1ec1 Testcontainers&quot;,&quot;width&quot;:&quot;0&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} - ({count} {votes})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 4px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 4px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 4px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 4px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 4px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 0px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 4px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 4px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 4px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 4px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 4px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 19.2px;\">\n            <span class=\"kksr-muted\"><\/span>\n    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>Testcontainers l\u00e0 m\u1ed9t th\u01b0 vi\u1ec7n gi\u00fap ch\u00fang ta c\u00f3 th\u1ec3 vi\u1ebft unit test cho c\u00e1c \u1ee9ng d\u1ee5ng, database ch\u1ea1y tr\u00ean m\u1ed9t Docker container. Testcontainers s\u1ebd gi\u00fap ch\u00fang ta ch\u1ea1y c\u00e1c \u1ee9ng d\u1ee5ng ho\u1eb7c database l\u00ean s\u1eed d\u1ee5ng c\u00e1c Docker Images, sau \u0111\u00f3 th\u00ec ch\u00fang ta&hellip; <a href=\"https:\/\/huongdanjava.com\/vi\/gioi-thieu-ve-testcontainers.html\">Read More<\/a><\/p>\n","protected":false},"author":1,"featured_media":21581,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2295],"tags":[],"class_list":["post-21464","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-testcontainers","clearfix"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Gi\u1edbi thi\u1ec7u v\u1ec1 Testcontainers - Huong Dan Java<\/title>\n<meta name=\"description\" content=\"Trong b\u00e0i vi\u1ebft n\u00e0y, m\u00ecnh gi\u1edbi thi\u1ec7u v\u1edbi c\u00e1c b\u1ea1n v\u1ec1 Testcontainers v\u00e0 c\u00e1ch s\u1eed d\u1ee5ng Testcontainers cho Java \u0111\u1ec3 vi\u1ebft unit test.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/huongdanjava.com\/vi\/gioi-thieu-ve-testcontainers.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Gi\u1edbi thi\u1ec7u v\u1ec1 Testcontainers - Huong Dan Java\" \/>\n<meta property=\"og:description\" content=\"Trong b\u00e0i vi\u1ebft n\u00e0y, m\u00ecnh gi\u1edbi thi\u1ec7u v\u1edbi c\u00e1c b\u1ea1n v\u1ec1 Testcontainers v\u00e0 c\u00e1ch s\u1eed d\u1ee5ng Testcontainers cho Java \u0111\u1ec3 vi\u1ebft unit test.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/huongdanjava.com\/vi\/gioi-thieu-ve-testcontainers.html\" \/>\n<meta property=\"og:site_name\" content=\"Huong Dan Java\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/nhkhanh2406\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/nhkhanh2406\" \/>\n<meta property=\"article:published_time\" content=\"2023-04-03T06:47:09+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-02-15T00:01:05+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/huongdanjava.com\/wp-content\/uploads\/2023\/04\/testcontainers.png\" \/>\n\t<meta property=\"og:image:width\" content=\"210\" \/>\n\t<meta property=\"og:image:height\" content=\"240\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Khanh Nguyen\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/KhanhNguyenJ\" \/>\n<meta name=\"twitter:site\" content=\"@KhanhNguyenJ\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Khanh Nguyen\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/huongdanjava.com\\\/vi\\\/gioi-thieu-ve-testcontainers.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/huongdanjava.com\\\/vi\\\/gioi-thieu-ve-testcontainers.html\"},\"author\":{\"name\":\"Khanh Nguyen\",\"@id\":\"https:\\\/\\\/huongdanjava.com\\\/#\\\/schema\\\/person\\\/dc859d7f8cbea3b593e6738de9cbb82d\"},\"headline\":\"Gi\u1edbi thi\u1ec7u v\u1ec1 Testcontainers\",\"datePublished\":\"2023-04-03T06:47:09+00:00\",\"dateModified\":\"2026-02-15T00:01:05+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/huongdanjava.com\\\/vi\\\/gioi-thieu-ve-testcontainers.html\"},\"wordCount\":983,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/huongdanjava.com\\\/#\\\/schema\\\/person\\\/dc859d7f8cbea3b593e6738de9cbb82d\"},\"image\":{\"@id\":\"https:\\\/\\\/huongdanjava.com\\\/vi\\\/gioi-thieu-ve-testcontainers.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/huongdanjava.com\\\/wp-content\\\/uploads\\\/2023\\\/04\\\/testcontainers.png\",\"articleSection\":[\"Testcontainers\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/huongdanjava.com\\\/vi\\\/gioi-thieu-ve-testcontainers.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/huongdanjava.com\\\/vi\\\/gioi-thieu-ve-testcontainers.html\",\"url\":\"https:\\\/\\\/huongdanjava.com\\\/vi\\\/gioi-thieu-ve-testcontainers.html\",\"name\":\"Gi\u1edbi thi\u1ec7u v\u1ec1 Testcontainers - Huong Dan Java\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/huongdanjava.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/huongdanjava.com\\\/vi\\\/gioi-thieu-ve-testcontainers.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/huongdanjava.com\\\/vi\\\/gioi-thieu-ve-testcontainers.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/huongdanjava.com\\\/wp-content\\\/uploads\\\/2023\\\/04\\\/testcontainers.png\",\"datePublished\":\"2023-04-03T06:47:09+00:00\",\"dateModified\":\"2026-02-15T00:01:05+00:00\",\"description\":\"Trong b\u00e0i vi\u1ebft n\u00e0y, m\u00ecnh gi\u1edbi thi\u1ec7u v\u1edbi c\u00e1c b\u1ea1n v\u1ec1 Testcontainers v\u00e0 c\u00e1ch s\u1eed d\u1ee5ng Testcontainers cho Java \u0111\u1ec3 vi\u1ebft unit test.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/huongdanjava.com\\\/vi\\\/gioi-thieu-ve-testcontainers.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/huongdanjava.com\\\/vi\\\/gioi-thieu-ve-testcontainers.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/huongdanjava.com\\\/vi\\\/gioi-thieu-ve-testcontainers.html#primaryimage\",\"url\":\"https:\\\/\\\/huongdanjava.com\\\/wp-content\\\/uploads\\\/2023\\\/04\\\/testcontainers.png\",\"contentUrl\":\"https:\\\/\\\/huongdanjava.com\\\/wp-content\\\/uploads\\\/2023\\\/04\\\/testcontainers.png\",\"width\":210,\"height\":240},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/huongdanjava.com\\\/vi\\\/gioi-thieu-ve-testcontainers.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/huongdanjava.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Gi\u1edbi thi\u1ec7u v\u1ec1 Testcontainers\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/huongdanjava.com\\\/#website\",\"url\":\"https:\\\/\\\/huongdanjava.com\\\/\",\"name\":\"Huong Dan Java\",\"description\":\"Java development tutorials\",\"publisher\":{\"@id\":\"https:\\\/\\\/huongdanjava.com\\\/#\\\/schema\\\/person\\\/dc859d7f8cbea3b593e6738de9cbb82d\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/huongdanjava.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/huongdanjava.com\\\/#\\\/schema\\\/person\\\/dc859d7f8cbea3b593e6738de9cbb82d\",\"name\":\"Khanh Nguyen\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/huongdanjava.com\\\/wp-content\\\/uploads\\\/2021\\\/07\\\/CC6FAC58-D227-4DD8-93D1-6D6A795577E3_1_201_a.jpeg\",\"url\":\"https:\\\/\\\/huongdanjava.com\\\/wp-content\\\/uploads\\\/2021\\\/07\\\/CC6FAC58-D227-4DD8-93D1-6D6A795577E3_1_201_a.jpeg\",\"contentUrl\":\"https:\\\/\\\/huongdanjava.com\\\/wp-content\\\/uploads\\\/2021\\\/07\\\/CC6FAC58-D227-4DD8-93D1-6D6A795577E3_1_201_a.jpeg\",\"width\":1267,\"height\":1517,\"caption\":\"Khanh Nguyen\"},\"logo\":{\"@id\":\"https:\\\/\\\/huongdanjava.com\\\/wp-content\\\/uploads\\\/2021\\\/07\\\/CC6FAC58-D227-4DD8-93D1-6D6A795577E3_1_201_a.jpeg\"},\"description\":\"I love Java and everything related to Java.\",\"sameAs\":[\"https:\\\/\\\/huongdanjava.com\",\"https:\\\/\\\/www.facebook.com\\\/nhkhanh2406\",\"https:\\\/\\\/x.com\\\/https:\\\/\\\/twitter.com\\\/KhanhNguyenJ\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Gi\u1edbi thi\u1ec7u v\u1ec1 Testcontainers - Huong Dan Java","description":"Trong b\u00e0i vi\u1ebft n\u00e0y, m\u00ecnh gi\u1edbi thi\u1ec7u v\u1edbi c\u00e1c b\u1ea1n v\u1ec1 Testcontainers v\u00e0 c\u00e1ch s\u1eed d\u1ee5ng Testcontainers cho Java \u0111\u1ec3 vi\u1ebft unit test.","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:\/\/huongdanjava.com\/vi\/gioi-thieu-ve-testcontainers.html","og_locale":"en_US","og_type":"article","og_title":"Gi\u1edbi thi\u1ec7u v\u1ec1 Testcontainers - Huong Dan Java","og_description":"Trong b\u00e0i vi\u1ebft n\u00e0y, m\u00ecnh gi\u1edbi thi\u1ec7u v\u1edbi c\u00e1c b\u1ea1n v\u1ec1 Testcontainers v\u00e0 c\u00e1ch s\u1eed d\u1ee5ng Testcontainers cho Java \u0111\u1ec3 vi\u1ebft unit test.","og_url":"https:\/\/huongdanjava.com\/vi\/gioi-thieu-ve-testcontainers.html","og_site_name":"Huong Dan Java","article_publisher":"https:\/\/www.facebook.com\/nhkhanh2406","article_author":"https:\/\/www.facebook.com\/nhkhanh2406","article_published_time":"2023-04-03T06:47:09+00:00","article_modified_time":"2026-02-15T00:01:05+00:00","og_image":[{"width":210,"height":240,"url":"https:\/\/huongdanjava.com\/wp-content\/uploads\/2023\/04\/testcontainers.png","type":"image\/png"}],"author":"Khanh Nguyen","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/KhanhNguyenJ","twitter_site":"@KhanhNguyenJ","twitter_misc":{"Written by":"Khanh Nguyen","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/huongdanjava.com\/vi\/gioi-thieu-ve-testcontainers.html#article","isPartOf":{"@id":"https:\/\/huongdanjava.com\/vi\/gioi-thieu-ve-testcontainers.html"},"author":{"name":"Khanh Nguyen","@id":"https:\/\/huongdanjava.com\/#\/schema\/person\/dc859d7f8cbea3b593e6738de9cbb82d"},"headline":"Gi\u1edbi thi\u1ec7u v\u1ec1 Testcontainers","datePublished":"2023-04-03T06:47:09+00:00","dateModified":"2026-02-15T00:01:05+00:00","mainEntityOfPage":{"@id":"https:\/\/huongdanjava.com\/vi\/gioi-thieu-ve-testcontainers.html"},"wordCount":983,"commentCount":0,"publisher":{"@id":"https:\/\/huongdanjava.com\/#\/schema\/person\/dc859d7f8cbea3b593e6738de9cbb82d"},"image":{"@id":"https:\/\/huongdanjava.com\/vi\/gioi-thieu-ve-testcontainers.html#primaryimage"},"thumbnailUrl":"https:\/\/huongdanjava.com\/wp-content\/uploads\/2023\/04\/testcontainers.png","articleSection":["Testcontainers"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/huongdanjava.com\/vi\/gioi-thieu-ve-testcontainers.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/huongdanjava.com\/vi\/gioi-thieu-ve-testcontainers.html","url":"https:\/\/huongdanjava.com\/vi\/gioi-thieu-ve-testcontainers.html","name":"Gi\u1edbi thi\u1ec7u v\u1ec1 Testcontainers - Huong Dan Java","isPartOf":{"@id":"https:\/\/huongdanjava.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/huongdanjava.com\/vi\/gioi-thieu-ve-testcontainers.html#primaryimage"},"image":{"@id":"https:\/\/huongdanjava.com\/vi\/gioi-thieu-ve-testcontainers.html#primaryimage"},"thumbnailUrl":"https:\/\/huongdanjava.com\/wp-content\/uploads\/2023\/04\/testcontainers.png","datePublished":"2023-04-03T06:47:09+00:00","dateModified":"2026-02-15T00:01:05+00:00","description":"Trong b\u00e0i vi\u1ebft n\u00e0y, m\u00ecnh gi\u1edbi thi\u1ec7u v\u1edbi c\u00e1c b\u1ea1n v\u1ec1 Testcontainers v\u00e0 c\u00e1ch s\u1eed d\u1ee5ng Testcontainers cho Java \u0111\u1ec3 vi\u1ebft unit test.","breadcrumb":{"@id":"https:\/\/huongdanjava.com\/vi\/gioi-thieu-ve-testcontainers.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/huongdanjava.com\/vi\/gioi-thieu-ve-testcontainers.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/huongdanjava.com\/vi\/gioi-thieu-ve-testcontainers.html#primaryimage","url":"https:\/\/huongdanjava.com\/wp-content\/uploads\/2023\/04\/testcontainers.png","contentUrl":"https:\/\/huongdanjava.com\/wp-content\/uploads\/2023\/04\/testcontainers.png","width":210,"height":240},{"@type":"BreadcrumbList","@id":"https:\/\/huongdanjava.com\/vi\/gioi-thieu-ve-testcontainers.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/huongdanjava.com\/"},{"@type":"ListItem","position":2,"name":"Gi\u1edbi thi\u1ec7u v\u1ec1 Testcontainers"}]},{"@type":"WebSite","@id":"https:\/\/huongdanjava.com\/#website","url":"https:\/\/huongdanjava.com\/","name":"Huong Dan Java","description":"Java development tutorials","publisher":{"@id":"https:\/\/huongdanjava.com\/#\/schema\/person\/dc859d7f8cbea3b593e6738de9cbb82d"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/huongdanjava.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/huongdanjava.com\/#\/schema\/person\/dc859d7f8cbea3b593e6738de9cbb82d","name":"Khanh Nguyen","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/huongdanjava.com\/wp-content\/uploads\/2021\/07\/CC6FAC58-D227-4DD8-93D1-6D6A795577E3_1_201_a.jpeg","url":"https:\/\/huongdanjava.com\/wp-content\/uploads\/2021\/07\/CC6FAC58-D227-4DD8-93D1-6D6A795577E3_1_201_a.jpeg","contentUrl":"https:\/\/huongdanjava.com\/wp-content\/uploads\/2021\/07\/CC6FAC58-D227-4DD8-93D1-6D6A795577E3_1_201_a.jpeg","width":1267,"height":1517,"caption":"Khanh Nguyen"},"logo":{"@id":"https:\/\/huongdanjava.com\/wp-content\/uploads\/2021\/07\/CC6FAC58-D227-4DD8-93D1-6D6A795577E3_1_201_a.jpeg"},"description":"I love Java and everything related to Java.","sameAs":["https:\/\/huongdanjava.com","https:\/\/www.facebook.com\/nhkhanh2406","https:\/\/x.com\/https:\/\/twitter.com\/KhanhNguyenJ"]}]}},"_links":{"self":[{"href":"https:\/\/huongdanjava.com\/wp-json\/wp\/v2\/posts\/21464","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/huongdanjava.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/huongdanjava.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/huongdanjava.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/huongdanjava.com\/wp-json\/wp\/v2\/comments?post=21464"}],"version-history":[{"count":13,"href":"https:\/\/huongdanjava.com\/wp-json\/wp\/v2\/posts\/21464\/revisions"}],"predecessor-version":[{"id":25061,"href":"https:\/\/huongdanjava.com\/wp-json\/wp\/v2\/posts\/21464\/revisions\/25061"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/huongdanjava.com\/wp-json\/wp\/v2\/media\/21581"}],"wp:attachment":[{"href":"https:\/\/huongdanjava.com\/wp-json\/wp\/v2\/media?parent=21464"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/huongdanjava.com\/wp-json\/wp\/v2\/categories?post=21464"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/huongdanjava.com\/wp-json\/wp\/v2\/tags?post=21464"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}