Testcontainer-03篇 MySQL

本文介绍如何使用TestContainer简化后端项目中MySQL数据库的测试过程,包括依赖引入、启动MySQL容器、配置数据库连接及使用特殊URL进行数据库初始化的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通常我们的后端项目中都离不开数据库的使用,然而在编写测试用例的时候却不是很好处理,这个时候,我们可以利用TestContainer来进行数据库的测试支持,这里使用我熟悉的MySQL。

一、引入依赖

<dependency>
   <groupId>org.testcontainers</groupId>
   <artifactId>testcontainers</artifactId>
   <version>1.12.0</version>
 </dependency>
<dependency>
   <groupId>org.mybatis.spring.boot</groupId>
   <artifactId>mybatis-spring-boot-starter</artifactId>
   <version>1.3.2</version>
 </dependency>
 <dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
 </dependency>
 <dependency>
   <groupId>org.testcontainers</groupId>
   <artifactId>mysql</artifactId>
   <version>1.12.0</version>
   <scope>test</scope>
 </dependency>

其中mybatis是我这里用到的一个持久层框架,大家根据自己的需要配置

二、使用testcontainer启动mysql

使用testcontainer启动mysql有两种方式:

  1. 使用注解@ClassRule / @Rule
  2. 使用特殊的url连接

首先,我们写出公用的代码,如下:
User类:

package com.firewolf.utils.testcontainer.mysql;

import lombok.Data;

@Data
public class User {

  private Integer id;
  private String name;
  private Integer age;
}

UserMapper接口:

package com.firewolf.utils.testcontainer.mysql;

import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

@Mapper
public interface UserMapper {

  @Select("select * from user")
  List<User> findUser();
}

(一)使用注解的方式

一般情况下,@Rule用处不是很大,因为这个只能在测试用例里面单独的使用,而不能注入到Spring容器中,所以我这里只记录@ClassRule用法

  1. 在类加载前启动容器
      @ClassRule
      public static MySQLContainer mysql = (MySQLContainer) new MySQLContainer("mysql:5.7")
          .withInitScript("db/init.sql");
    
    这里引入了初始化脚本(如果你有初始的数据库脚本),脚本所在目录为resources下面
    init.sql内容如下:
    CREATE TABLE `user` (
                            `name` varchar(255) DEFAULT NULL,
                            `age` int(11) DEFAULT NULL,
                            `id` int(11) NOT NULL AUTO_INCREMENT,
                            PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    insert into `user` (`name`,`age`) values ('lisi',30);
    insert into `user` (`name`,`age`) values ('wangwu',30);
    insert into `user` (`name`,`age`) values ('赵六',15);
    
    
  2. 为Spring容器注入连接属性
    @BeforeClass
    public static void init() {
      System.setProperty("spring.datasource.url", mysql.getJdbcUrl());
      System.setProperty("spring.datasource.driver-class-name", mysql.getDriverClassName());
      System.setProperty("spring.datasource.username", mysql.getUsername());
      System.setProperty("spring.datasource.password", mysql.getPassword());
    }
    
    这样的话,Spring在初始化数据源的时候,就能够连接上数据库
  3. 注入UserMapper并使用
      @Autowired
      private UserMapper userMapper;
      @Test
      public void testUserMapper() {
        List<User> userList = userMapper.findUser();
        assert userList.size() == 3;
        System.out.println("查询到的用户列表如下:");
        System.out.println(userList);
      }
    
  4. 完整代码为
    package com.firewolf.utils.testcontainer.mysql;
    
    import com.firewolf.utils.testcontainer.TestcontainerApplication;
    import java.util.List;
    import org.junit.BeforeClass;
    import org.junit.ClassRule;
    import org.junit.Ignore;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.testcontainers.containers.MySQLContainer;
    @SpringBootTest(classes = TestcontainerApplication.class)
    @RunWith(SpringRunner.class)
    public class MySQLDriver2 {
      @Autowired
      private UserMapper userMapper;
    
      @ClassRule
      public static MySQLContainer mysql = (MySQLContainer) new MySQLContainer("mysql:5.7")
          .withInitScript("db/init.sql");
      /**
       * 设置数据库连接属性
       */
      @BeforeClass
      public static void init() {
        System.setProperty("spring.datasource.url", mysql.getJdbcUrl());
        System.setProperty("spring.datasource.driver-class-name", mysql.getDriverClassName());
        System.setProperty("spring.datasource.username", mysql.getUsername());
        System.setProperty("spring.datasource.password", mysql.getPassword());
      }
    
      @Test
      public void testUserMapper() {
        List<User> userList = userMapper.findUser();
        assert userList.size() == 3;
        System.out.println("查询到的用户列表如下:");
        System.out.println(userList);
      }
    }
    

这种用法的话,在Spring配置文件中不需要配置数据库连接的四个关键属性,其他的可以自行配置;

如果只是在某个测试用例里面用到数据库,我们可以直接在测试用例里面启动mysql容器即可,如:

public void testSimple() {
  MySQLContainer mysql = (MySQLContainer) new MySQLContainer("mysql:5.7")
      .withInitScript("db/init.sql");
  mysql.start();

  System.out.println(mysql.getJdbcUrl());
  System.out.println(mysql.getDriverClassName());
  System.out.println(mysql.getUsername());
  System.out.println(mysql.getPassword());

}

(二)使用特殊的URL

这种方式的测试用例类非常简答,没有任何容器相关内容,先贴出来:

package com.firewolf.utils.testcontainer.mysql;

import com.firewolf.utils.testcontainer.TestcontainerApplication;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;


@SpringBootTest(classes = TestcontainerApplication.class)
@RunWith(SpringRunner.class)
public class MySQLDriver {

  @Autowired
  private UserMapper userMapper;

  @Test
  public void test() {
    List<User> userList = userMapper.findUser();
    assert userList.size() == 3;
    System.out.println("查询到的用户列表如下:");
    System.out.println(userList);
  }
}

那么怎么引入testcontainer呢,其实很简答,就在我们的配置文件中对url进行处理,如下:

#mysql
spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver
spring.datasource.url=jdbc:tc:mysql:5.7://localhost:3306/testdb?TC_INITSCRIPT=db/init.sql
spring.datasource.username=root
spring.datasource.password=111111
#mybatis下划线转驼峰命名
mybatis.configuration.map-underscore-to-camel-case=true

我们可以看到,和正常配置URL不同的是,这里在jdbc后面添加了tc
同时我们还看到,可以通过TC_INITSCRIPT来指定初始化脚本的位置;

对于URL这种方式,我们还可以使用类来进行数据库初始化,方式如下:

  1. 改变URL为:
    spring.datasource.url=jdbc:tc:mysql:5.7://localhost:3306/testdb?TC_INITFUNCTION=com.firewolf.utils.testcontainer.mysql.DataSourceInit::initFunction
    
    这里使用TC_INITFUNCTION来指定了初始化的类和方法
  2. 编写初始化方法
    package com.firewolf.utils.testcontainer.mysql;
    
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Arrays;
    
    public class DataSourceInit {
    
      public static void initFunction(Connection connection) throws Exception {
        Statement statement = connection.createStatement();
    
        String[] sqls = new String[]{
    
            "CREATE TABLE `user` (\n"
                + "                        `name` varchar(255) DEFAULT NULL,\n"
                + "                        `age` int(11) DEFAULT NULL,\n"
                + "                        `id` int(11) NOT NULL AUTO_INCREMENT,\n"
                + "                        PRIMARY KEY (`id`)\n"
                + ") ENGINE=InnoDB DEFAULT CHARSET=utf8",
            "insert into `user` (`name`,`age`) values ('bajie',30)",
            "insert into `user` (`name`,`age`) values ('wukong',1000)",
            "insert into `user` (`name`,`age`) values ('唐僧',600)",
        };
    
        Arrays.stream(sqls).forEach(x -> {
          try {
            statement.execute(x);
          } catch (SQLException e) {
            e.printStackTrace();
          }
        });
      }
    }
    
    
vs2010 中添加 ActiveX Control Test Container工具(转载) vs2010中的TSTCON( ActiveX Control Test Container )工具非自动安装,而是作为一个例程提供。所以应找到该例程,并编译: 如vs2010安装在默认路径则 1, 进入:C:\Program Files\Microsoft Visual Studio 10.0\Samples\1033,可找到VC2010Samples.zip文件, 2, 将其解决到同一个文件夹,解压后将出现一个C++子文件夹。 3, TstCon例程在:C:\Program Files\Microsoft Visual Studio 10.0\Samples\1033\C++\MFC\ole\TstCon,双击其中的.sln文件启动工程,直接编译, 4, 编译后在Debug子文件夹中将出现一个TstCon.exe文件,将其复制到:C:\Program Files\Microsoft Visual Studio 10.0\Common7\Tools文件夹。 5, 在vs2010中的Tools菜单点击“External Tools...”,出现如下对话框,点击“Add”添加一项工具。 6, 新工具项的"Title"为:ActiveX Control Test Container,"Command"为:C:\Program Files\Microsoft Visual Studio 10.0\Common7\Tools\TstCon.exe。 7, 确认退出对话框,Tools菜单将出现“ActiveX Control Test Container”菜单项。完毕! 同理在2015安装目录下找到并编译: 但是编译的时候需要区分win32和x64的不同平台生成的工具 分别添加 ActiveX Control Test Container 32和 ActiveX Control Test Container 64的工具,因为不同工具显示的是不同平台注册的com组件,比如你注册一个32位的com组件,此时只能用ActiveX Control Test Container 32测试,而在ActiveX Control Test Container 64中是找不到这个com组件的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值