Spring boot Mybatis-Plus database single test actual combat (three ways)

  Unit testing has long been a hot topic, this article will not discuss or need to write a single test, you can see reference material 1 , I personally think that a single measure should be written every good developer the necessary skills, written on a single measurement of I won't discuss the benefits here, and quickly enter the topic that this article focuses on, how to write a good database single test.

  Why do you want to write a database single test? I believe you have such a similar experience, after writing complex SQL statements, confidently raised the test, and found that a large part of the bug is because of problems with the SQL statement, or write less The comma, or the field is missing, I regret that I wow, why not test it after writing it!

  It's ok! This will teach you how to write a database single test, allowing you to easily say goodbye to database-related bugs.

1. Database sample and environment

  Let's start this tutorial with the user table as an example:
user table

Figure 1.1 User table ER diagram

  After introducing the mybatis-plus plug-in, the mapper class is as follows:

@Mapper
public interface UserMapper  extends BaseMapper<UserDO> {
    
    
}

  Overall environment:

  1. spring boot: 1.5.18.RELEASE
  2. mybatis: 3.5.1
  3. mybatis plus: 3.4.0 (the latest version at this time, we will use the features of the latest version)

  Here we directly test some CRUDs provided by mybatis plus. Of course, these CRUDs are generally not wrong. In actual projects, we only need to unit test the custom SQL.

2. Method 1: Start the entire environment

  This method should be the most commonly used in daily environments . The @SpringBootTest annotation introduced by SpringBoot since version 1.4.0 can start all the environments needed for our unit testing. Of course, if you use other distributed services in your project, he will also These services will also be started. The single test code is as follows:

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {
    
    

    @Autowired
    private UserMapper userMapper;


    @Test
    public void testCurd() {
    
    
        UserDO userDO = new UserDO();
        userDO.setId(7777L);
        userDO.setGmtModified(new Date());
        userDO.setGmtCreate(new Date());
        userDO.setRealName("ke");
        userDO.setUserName("ni");
        userMapper.insert(userDO);

        UserDO select = userMapper.selectById(1);
        System.out.println(select);
    }
}

@SpringBootTest annotation can set the classes that need to be started and loaded on demand

3. Method 2: Only start the database environment + remote database

  In reference 2, test starter is introduced in the latest mybatis-plus release version (3.4.0), as shown in the figure:

New features of Mybatis-plus 3.4.0

Figure 3.1 Mybatis-plus 3.4.0 introduces the test module

  The module introduces a new annotation @MybatisPlusTest, this annotation can help us only start a specific specific module, directly on the single test code:

@RunWith(SpringRunner.class)
@MybatisPlusTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
public class UserMapperTest {
    
    

    @Autowired
    private UserMapper userMapper;


    @Test
    public void testCurd() {
    
    
        UserDO userDO = new UserDO();
        userDO.setId(7777L);
        userDO.setGmtModified(new Date());
        userDO.setGmtCreate(new Date());
        userDO.setRealName("ke");
        userDO.setUserName("ni");
        userMapper.insert(userDO);

        UserDO select = userMapper.selectById(1);
        System.out.println(select);
    }
}

  Is it easy? But we should pay attention to the following key points:

  • @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)The role is to use a custom data source instead of an automatically configured embedded memory data source
  • If you are using a connection pool similar to druid in your project, you need to use the jdbc data source directly in the application configuration file in the test module, because the @MybatisPlusTestannotation will not start the connection pool framework. The typical configuration file application.yml is as follows:
spring:
  datasource:
    url: jdbc:mysql://xxx.xxx.1.110:3306/test?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: 123456

4. Method 3: Only start the database environment + local database

  On the basis of Method 2, proceed as follows:

  1. We remove the @AutoConfigureTestDatabasannotations and start testing the embedded database directly. Here we choose H2 memory database, first introduce H2 database maven dependency in pom;
  2. Then introduce the sechema.sql file in the test environment, this file is used to initialize the database, the core is to create a table statement;
  3. Finally, after removing this page, the writing method is the same as the way two, so I won’t give it here.

Note: The sechema.sql file must conform to the syntax of the embedded database. In this case, it is the h2 database. If you are using the mysql database, you need to convert the mysql database syntax to the h2 database syntax.

5. @MybatisPlusTest annotation principle

  If you have used the MyBatis-Spring-Boot-Starter-Test @MybatisTest(Reference 3) before, you will find that the @MybatisPlusTestannotation principle is similar to it, all of which restrict the automatic configuration of spring boot (Reference 4), and only need to load specific The configuration can be. Let's take a look at the annotation source code:

@Target({
    
    ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@BootstrapWith(MybatisPlusTestContextBootstrapper.class)
@ExtendWith({
    
    SpringExtension.class})
@OverrideAutoConfiguration(
    enabled = false
)
@TypeExcludeFilters({
    
    MybatisPlusTypeExcludeFilter.class})
@Transactional
@AutoConfigureCache
@AutoConfigureMybatisPlus
@AutoConfigureTestDatabase
@ImportAutoConfiguration
public @interface MybatisPlusTest {
    
    
    String[] properties() default {
    
    };

    boolean useDefaultFilters() default true;

    Filter[] includeFilters() default {
    
    };

    Filter[] excludeFilters() default {
    
    };

    @AliasFor(
        annotation = ImportAutoConfiguration.class,
        attribute = "exclude"
    )
    Class<?>[] excludeAutoConfiguration() default {
    
    };
}
  • @OverrideAutoConfiguration(enabled = false)Is the key, it turns off the automatic configuration, and generally in the spring boot project, enable is turned on;
  • @AutoConfigureMybatisPlusThe annotation is a custom annotation. This annotation defines all the required loading classes to be loaded. The classes to be automatically configured are declared in spring.factories:
# AutoConfigureMybatis auto-configuration imports
com.baomidou.mybatisplus.test.autoconfigure.AutoConfigureMybatisPlus=\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
com.baomidou.mybatisplus.autoconfigure.MybatisPlusLanguageDriverAutoConfiguration,\
com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration

  • @AutoConfigureTestDatabaseThe annotation indicates that the in-memory database is used instead of the real database

  With these restrictions and regulations, mybatis-plus can automatically load the required configuration in the test environment, thus removing the loading of unnecessary resources.

6. Summary

Three database single test summary

Figure 6.1 Single test summary of three databases

  If you are using mysql database, I recommend the second method. If you can solve the problem of converting mysq grammar to h2, it is recommended to use method three, so that you can perform a single test in offline situations without connecting to a remote database.

PS: If you have a good tool to complete the mysql conversion h2, you can recommend it in the comment area. I have been looking for it for a long time, including custom writing conversion, some professional tools, etc., I feel that the conversion of the sentences exported by Navicat is not very Works well.

7. Reference materials

[1] Do you really need unit testing?
[2] Mybatis-Plus release version
[3] MyBatis-Spring-Boot-Starter-Test
[4] Auto-configuration of SpringBoot's four artifacts

Guess you like

Origin blog.csdn.net/u012397189/article/details/109288747