JavaRush /Blog Jawa /Random-JV /Pengujian integrasi database nggunakake MariaDB kanggo ng...

Pengujian integrasi database nggunakake MariaDB kanggo ngganti MySql

Diterbitake ing grup
Pengujian integrasi database nggunakake MariaDB kanggo ngganti MySql - 1Dina iki aku arep ngomong babagan tes, amarga luwih akeh kode kasebut ditutupi karo tes, luwih apik lan luwih dipercaya. Ayo dadi pirembagan ora bab testing unit, nanging bab testing integrasi database. Apa sejatine bedane tes unit lan tes integrasi? Pengujian integrasi database nggunakake MariaDB kanggo ngganti MySql - 2Modular (unit) nguji program ing tingkat modul, metode utawa kelas individu, yaiku, tes cepet lan gampang, mengaruhi bagean sing paling bisa dibagi saka fungsi kasebut. Dheweke uga diarani "siji tes saben metode". Integrasi luwih alon lan luwih abot, lan bisa kalebu sawetara modul lan fungsi tambahan. Pengujian integrasi database nggunakake MariaDB kanggo ngganti MySql - 3Napa tes kanggo tes integrasi lapisan dao (Obyek Akses Data)? Amarga kanggo nyoba cara karo pitakon menyang database, kita kudu ngunggahake database kapisah ing RAM, ngganti sing utama. Ing idea iku kita nggawe tabel kita kudu, isi karo data test lan mriksa bener saka cara kelas gudang (sawise kabeh, kita ngerti apa asil final kudu ing kasus tartamtu). Dadi, ayo miwiti. Topik kanggo nyambungake database wis dawa wis dijamin adoh, lan mulane dina iki aku ora kaya kanggo manggon ing bab iki, lan kita bakal nimbang mung bagean saka program sing kapentingan kita. Kanthi gawan, kita bakal miwiti saka kasunyatan manawa aplikasi kita adhedhasar Spring Boot, kanggo lapisan dao Spring JDBC (kanggo luwih cetha), database utama kita yaiku MySQL, lan kita bakal ngganti nggunakake MariaDB (padha kompatibel maksimal, lan Mulane, skrip MySQL ora bakal ana konflik karo dialek MariaDB, kaya sing bakal ana karo H2). Kita uga bakal nganggep yen program kita nggunakake Liquibase kanggo ngatur lan ngetrapake owah-owahan ing skema database, lan kanthi mangkono, kabeh skrip sing ditrapake disimpen ing aplikasi kita.

Struktur proyek

Mung bagean sing kena pengaruh ditampilake: Pengujian integrasi database nggunakake MariaDB kanggo ngganti MySql - 5Lan ya, dina iki kita bakal nggawe robot)) Pengujian integrasi database nggunakake MariaDB kanggo ngganti MySql - 6Script kanggo tabel, cara sing bakal dites dina iki (create_table_robots.sql):
CREATE TABLE `robots`
(
   `id`   BIGINT(20) NOT NULL AUTO_INCREMENT,
   `name` CHAR(255) CHARACTER SET utf8 NOT NULL,
   `cpu`  CHAR(255) CHARACTER SET utf8 NOT NULL,
   `producer`  CHAR(255) CHARACTER SET utf8 NOT NULL,
   PRIMARY KEY (`id`)
) ENGINE = InnoDB
 DEFAULT CHARSET = utf8;
Entitas sing makili tabel iki:
@Builder
@Data
public class Robot {

   private Long id;

   private String name;

   private String cpu;

   private String producer;
}
Antarmuka kanggo repositori sing dites:
public interface RobotDAO {

   Robot findById(Long id);

   Robot create(Robot robot);

   List<Robot> findAll();

   Robot update(Robot robot);

   void delete(Long id);
}
Bener, ing kene ana operasi CRUD standar, tanpa eksotik, mula kita bakal nimbang implementasine ora kabeh cara (uga, iki ora bakal kaget sapa wae), nanging sawetara - luwih ringkes:
@Repository
@AllArgsConstructor
public class RobotDAOImpl implements RobotDAO {

   private static final String FIND_BY_ID = "SELECT id, name, cpu, producer FROM robots WHERE id = ?";

   private static final String UPDATE_BY_ID = "UPDATE robots SET name = ?, cpu = ?, producer = ?  WHERE id = ?";

   @Autowired
   private final JdbcTemplate jdbcTemplate;

   @Override
   public Robot findById(Long id) {
       return jdbcTemplate.queryForObject(FIND_BY_ID, robotMapper(), id);
   }

   @Override
   public Robot update(Robot robot) {
       jdbcTemplate.update(UPDATE_BY_ID,
               robot.getName(),
               robot.getCpu(),
               robot.getProducer(),
               robot.getId());

       return robot;
   }

   private RowMapper<Robot> robotMapper() {
       return (rs, rowNum) ->
               Robot.builder()
                       .id(rs.getLong("id"))
                       .name(rs.getString("name"))
                       .cpu(rs.getString("cpu"))
                       .producer(rs.getString("producer"))
                       .build();
   }
Ayo njupuk digression sethithik lan deleng apa sing kedadeyan karo dependensi kita (mung sing digunakake kanggo bagean aplikasi sing dituduhake):
<dependencies>
   <dependency>
       <groupId>org.mariadb.jdbc</groupId>
       <artifactId>mariadb-java-client</artifactId>
       <version>2.5.2</version>
       <scope>test</scope>
   </dependency>
   <dependency>
       <groupId>org.craftercms.mariaDB4j</groupId>
       <artifactId>mariaDB4j-springboot</artifactId>
       <version>2.4.2.3</version>
       <scope>test</scope>
   </dependency>
   <dependency>
       <groupId>org.projectlombok</groupId>
       <artifactId>lombok</artifactId>
       <version>1.18.10</version>
       <scope>provided</scope>
   </dependency>
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-test</artifactId>
       <version>2.2.1.RELEASE</version>
       <scope>test</scope>
   </dependency>
   <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-jdbc</artifactId>
       <version>2.2.1.RELEASE</version>
   </dependency>
</dependencies>
4 - dependensi kanggo database MariaDb dhewe 10 - dependensi kanggo nyambungake karo SpringBoot 16 - Lombok (uga, aku kabeh ngerti apa jenis lib iki) 22 - wiwitan kanggo tes (ngendi JUnit kita kudu ditempelake) 28 - wiwitan kanggo nggarap springJdbc Ayo goleki Wadah musim semi karo kacang buncis sing dibutuhake kanggo tes kita (utamane, kacang kreasi MariaDB):
@Configuration
public class TestConfigDB {

   @Bean
   public MariaDB4jSpringService mariaDB4jSpringService() {
       return new MariaDB4jSpringService();
   }

   @Bean
   public DataSource dataSource(MariaDB4jSpringService mariaDB4jSpringService) {
       try {
           mariaDB4jSpringService.getDB().createDB("testDB");
       } catch (ManagedProcessException e) {
         e.printStackTrace();
       }

       DBConfigurationBuilder config = mariaDB4jSpringService.getConfiguration();

       return DataSourceBuilder
               .create()
               .username("root")
               .password("root")
               .url(config.getURL("testDB"))
               .driverClassName("org.mariadb.jdbc.Driver")
               .build();
   }

   @Bean
   public JdbcTemplate jdbcTemplate(DataSource dataSource) {
       return new JdbcTemplate(dataSource);
   }
}
5 - komponen utama kanggo ngunggahake MariaDB (kanggo aplikasi adhedhasar Spring Framework) 10 - nemtokake kacang database 12 - nyetel jeneng Database sing digawe 17 - narik metu konfigurasi kanggo kasus kita 19 - mbangun database nggunakake pola Builder ( Ringkesan apik saka pola ) Lan pungkasanipun, apa kabeh fuss bab iku kacang JdbcTemplate kanggo komunikasi karo database wungu. Ide kasebut yaiku kita bakal duwe kelas utama kanggo tes Tao, saka ngendi kabeh kelas tes Tao bakal diwenehi warisan, sing tugase kalebu:
  1. ngluncurake sawetara skrip sing digunakake ing basis data utama (skrip kanggo nggawe tabel, ngganti kolom, lan liya-liyane);
  2. ngluncurake skrip tes sing ngisi tabel kanthi data tes;
  3. mbusak tabel.
@SpringBootTest(classes = TestConfigDB.class)
public abstract class DataBaseIT {

   @Autowired
   private JdbcTemplate jdbcTemplate;

   public JdbcTemplate getJdbcTemplate() {
       return jdbcTemplate;
   }

   public void fillDataBase(String[] initList) {
       for (String x : initList) {
           try {
               jdbcTemplate.update(IOUtils.resourceToString("/db.migrations/" + x, StandardCharsets.UTF_8));
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
   }

   public void cleanDataBase() {
       getJdbcTemplate().update("DROP database testDB");
       getJdbcTemplate().update("CREATE database testDB");
       getJdbcTemplate().update("USE testDB");
   }

   public void fillTables(String[] fillList) {
       for (String x : fillList) {
           try {
               Stream.of(
                       IOUtils.resourceToString("/fill_scripts/" + x, StandardCharsets.UTF_8))
                       .forEach(jdbcTemplate::update);
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
   }
}
1 - nggunakake anotasi @SpringBootTest kita nyetel konfigurasi tes 11 - minangka argumen ing metode iki, kita menehi jeneng tabel sing kita butuhake, lan dheweke, minangka pekerja keras sing tanggung jawab, bakal mbukak kanggo kita (sing menehi kesempatan kanggo kita. kanggo nggunakake maneh cara iki kaya sing dikarepake) 21 - kita nggunakake cara iki kanggo ngresiki, yaiku, mbusak kabeh tabel (lan data) saka database 27 - argumen ing metode iki yaiku susunan jeneng skrip kanthi data tes. sing bakal dimuat kanggo nguji metode tartamtu. Skrip kita karo data uji:
INSERT INTO robots(name, cpu, producer)
VALUES ('Rex', 'Intel Core i5-9400F', 'Vietnam'),
      ('Molly', 'AMD Ryzen 7 2700X', 'China'),
      ('Ross', 'Intel Core i7-9700K', 'Malaysia')
Lan saiki apa sing wis kita kumpulake kanggo dina iki.

Kelas tes Tao

@RunWith(SpringRunner.class)
public class RobotDataBaseIT extends DataBaseIT {

   private static RobotDAO countryDAO;

   @Before
   public void fillData() {
       fillDataBase(new String[]{
               "create_table_robots.sql"
       });
       countryDAO = new RobotDAOImpl(getJdbcTemplate());
   }

   @After
   public void clean() {
       cleanDataBase();
   }

   private RowMapper<Robot> robotMapper() {
       return (rs, rowNum) ->
               Robot.builder()
                       .id(rs.getLong("id"))
                       .name(rs.getString("name"))
                       .cpu(rs.getString("cpu"))
                       .producer(rs.getString("producer"))
                       .build();
   }
2 - kita entuk warisan saka kelas utama kanggo tes kita 4 - gudang sing diuji 7 - cara sing bakal diluncurake sadurunge saben tes 8 - kita nggunakake metode kelas induk kanggo mbukak tabel sing dibutuhake 11 - kita miwiti dao 15 - metode sing bakal diluncurake sawise saben test, ngresiki database kita 19 - implementasine RowMapper kita, analog karo kelas Tao Kita nggunakake @Before lan @After, sing digunakake sadurunge lan sawise siji cara test, nanging kita bisa njupuk sawetara lib sing ngidini kita nggunakake anotasi sing disambungake karo wiwitan tes eksekusi kelas iki lan pungkasan. Contone, iki , sing bakal nyepetake tes kanthi signifikan, amarga tabel kudu digawe lan dibusak kabeh saben wektu, lan sapisan saben kelas. Nanging kita ora nglakoni. Ngopo kowe takon? Apa yen salah sawijining metode ngganti struktur tabel? Contone, mbusak siji kolom. Ing kasus iki, cara sing isih ana bisa uga gagal utawa kudu nanggapi kaya sing dikarepake (contone, nggawe kolom mburi). Kita kudu ngakoni manawa iki menehi sambungan (ketergantungan) tes sing ora perlu, sing ora ana gunane kanggo kita. Nanging aku nglirwakake, ayo terus ...

Nguji metode findById

@Test
public void findByIdTest() {
   fillTables(new String[]{"fill_table_robots.sql"});

   Long id = getJdbcTemplate().queryForObject("SELECT id FROM robots WHERE name = 'Molly'", Long.class);
   Robot robot = countryDAO.findById(id);

   assertThat(robot).isNotNull();
   assertThat(robot.getId()).isEqualTo(id);
   assertThat(robot.getName()).isEqualTo("Molly");
   assertThat(robot.getCpu()).isEqualTo("AMD Ryzen 7 2700X");
   assertThat(robot.getProducer()).isEqualTo("China");
}
3 - ngisi tabel kanthi data uji 5 - entuk id kanggo entitas sing dibutuhake 6 - nggunakake metode sing diuji 8...12 - mbandhingake data sing ditampa karo sing dikarepake

Tes metode nganyari

@Test
public void updateTest() {
   fillTables(new String[]{"fill_table_robots.sql"});

   Long robotId = getJdbcTemplate().queryForObject("SELECT id FROM robots WHERE name = 'Rex'", Long.class);

   Robot updateRobot = Robot.builder()
           .id(robotId)
           .name("Aslan")
           .cpu("Intel Core i5-3470")
           .producer("Narnia")
           .build();

   Robot responseRobot = countryDAO.update(updateRobot);
   Robot updatedRobot = getJdbcTemplate().queryForObject(
           "SELECT id, name, cpu, producer FROM robots WHERE id = ?",
           robotMapper(),
           robotId);

   assertThat(updatedRobot).isNotNull();
   assertThat(updateRobot.getName()).isEqualTo(responseRobot.getName());
   assertThat(updateRobot.getName()).isEqualTo(updatedRobot.getName());
   assertThat(updateRobot.getCpu()).isEqualTo(responseRobot.getCpu());
   assertThat(updateRobot.getCpu()).isEqualTo(updatedRobot.getCpu());
   assertThat(updateRobot.getProducer()).isEqualTo(responseRobot.getProducer());
   assertThat(updateRobot.getProducer()).isEqualTo(updatedRobot.getProducer());
   assertThat(responseRobot.getId()).isEqualTo(updatedRobot.getId());
   assertThat(updateRobot.getId()).isEqualTo(updatedRobot.getId());
}
3 - ngisi tabel kanthi data uji 5 - entuk id entitas sing dianyari 7 - mbangun entitas sing dianyari 14 - nggunakake metode sing diuji 15 - entuk entitas sing dianyari kanggo verifikasi 20...28 - mbandhingake data sing ditampa karo sing samesthine Testing cara nganyari padha karo nggawe. Paling kanggo kula. Sampeyan bisa ngowahi rekonsiliasi kaya sing dikarepake: ora bakal ana cek sing akeh banget. Aku uga pengin nyathet yen tes ora njamin fungsi lengkap utawa ora ana kewan omo. Tes mung mesthekake yen asil nyata saka program (fragmen) cocog karo sing dikarepake. Ing kasus iki, mung bagean sing wis ditulis tes sing dicenthang.

Ayo miwiti kelas kanthi tes ...

Pengujian integrasi database nggunakake MariaDB kanggo ngganti MySql - 7Kamenangan)) Ayo nggawe teh lan njaluk cookie: kita pantes)) Pengujian integrasi database nggunakake MariaDB kanggo ngganti MySql - 8

pranala migunani

Kanggo sing wis rampung maca, matur nuwun kanggo perhatian lan ... Pengujian integrasi database nggunakake MariaDB kanggo ngganti MySql - 9

*musik Star Wars epik*

Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION