JavaRush /Blog Java /Random-MS /Ujian integrasi pangkalan data menggunakan MariaDB untuk ...

Ujian integrasi pangkalan data menggunakan MariaDB untuk menggantikan MySql

Diterbitkan dalam kumpulan
Ujian integrasi pangkalan data menggunakan MariaDB untuk menggantikan MySql - 1Hari ini saya ingin bercakap tentang ujian, kerana lebih banyak kod itu diliputi dengan ujian, lebih baik dan lebih dipercayai ia dipertimbangkan. Mari kita bercakap bukan tentang ujian unit, tetapi tentang ujian penyepaduan pangkalan data. Apakah sebenarnya perbezaan antara ujian unit dan ujian integrasi? Ujian integrasi pangkalan data menggunakan MariaDB untuk menggantikan MySql - 2Modular (unit) sedang menguji program pada tahap modul, kaedah atau kelas individu, iaitu, ujian adalah pantas dan mudah, menjejaskan bahagian fungsi yang paling boleh dibahagikan. Mereka juga dirujuk sebagai "satu ujian setiap kaedah". Penyepaduan adalah lebih perlahan dan lebih berat, dan boleh terdiri daripada beberapa modul dan fungsi tambahan. Ujian integrasi pangkalan data menggunakan MariaDB untuk menggantikan MySql - 3Mengapakah ujian untuk ujian integrasi lapisan dao (Objek Akses Data)? Kerana untuk menguji kaedah dengan pertanyaan ke pangkalan data, kita perlu menaikkan pangkalan data berasingan dalam RAM, menggantikan yang utama. Ideanya ialah kami mencipta jadual yang kami perlukan, mengisinya dengan data ujian dan menyemak ketepatan kaedah kelas repositori (lagipun, kami tahu keputusan akhir yang sepatutnya dalam kes tertentu). Jadi, mari kita mulakan. Topik mengenai penyambungan pangkalan data telah lama diliputi jauh dan luas, dan oleh itu hari ini saya tidak ingin membincangkan perkara ini, dan kami akan mempertimbangkan hanya bahagian program yang menarik minat kami. Secara lalai, kami akan bermula dari fakta bahawa aplikasi kami adalah berdasarkan Spring Boot, untuk lapisan dao Spring JDBC (untuk lebih jelas), pangkalan data utama kami ialah MySQL, dan kami akan menggantikannya menggunakan MariaDB (mereka serasi secara maksimum, dan oleh itu skrip MySQL tidak akan pernah ada konflik dengan dialek MariaDB, seperti yang akan berlaku dengan H2). Kami juga akan bersyarat menganggap bahawa program kami menggunakan Liquibase untuk mengurus dan menggunakan perubahan pada skema pangkalan data, dan dengan itu, semua skrip yang digunakan disimpan dalam aplikasi kami.

Struktur projek

Hanya bahagian yang terjejas ditunjukkan: Ujian integrasi pangkalan data menggunakan MariaDB untuk menggantikan MySql - 5Dan ya, hari ini kita akan mencipta robot)) Ujian integrasi pangkalan data menggunakan MariaDB untuk menggantikan MySql - 6Skrip untuk jadual, kaedah yang akan kita uji hari ini (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;
Entiti yang mewakili jadual ini:
@Builder
@Data
public class Robot {

   private Long id;

   private String name;

   private String cpu;

   private String producer;
}
Antara muka untuk repositori yang diuji:
public interface RobotDAO {

   Robot findById(Long id);

   Robot create(Robot robot);

   List<Robot> findAll();

   Robot update(Robot robot);

   void delete(Long id);
}
Sebenarnya, berikut adalah operasi CRUD standard, tanpa eksotik, jadi kami akan mempertimbangkan pelaksanaan bukan semua kaedah (baik, ini tidak akan mengejutkan sesiapa pun), tetapi beberapa - untuk lebih ringkas:
@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();
   }
Mari kita ambil sedikit penyimpangan dan lihat apa yang berlaku dengan kebergantungan kita (hanya yang digunakan untuk bahagian yang ditunjukkan dalam aplikasi dibentangkan):
<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 - pergantungan untuk pangkalan data MariaDb itu sendiri 10 - pergantungan untuk menyambung dengan SpringBoot 16 - Lombok (baik, saya rasa semua orang tahu jenis lib ini) 22 - pemula untuk ujian (di mana JUnit yang kita perlukan dibenamkan) 28 - pemula untuk bekerja dengan springJdbc Mari kita lihat bekas Spring dengan kacang yang diperlukan untuk ujian kami (khususnya, kacang penciptaan 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 untuk menaikkan MariaDB (untuk aplikasi berdasarkan Rangka Kerja Spring) 10 - mentakrifkan kacang pangkalan data 12 - menetapkan nama Pangkalan Data yang dibuat 17 - menarik keluar konfigurasi untuk kes kami 19 - membina pangkalan data menggunakan corak Pembina ( gambaran keseluruhan corak yang baik ) Dan akhirnya, apa yang menjadi kecoh ialah kacang JdbcTemplate untuk komunikasi dengan pangkalan data yang dibangkitkan. Ideanya ialah kami akan mempunyai kelas utama untuk ujian Tao, yang daripadanya semua kelas ujian Dao akan diwarisi, yang tugasnya termasuk:
  1. melancarkan beberapa skrip yang digunakan dalam pangkalan data utama (skrip untuk mencipta jadual, menukar lajur, dan lain-lain);
  2. melancarkan skrip ujian yang mengisi jadual dengan data ujian;
  3. memadam jadual.
@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 - menggunakan anotasi @SpringBootTest kami menetapkan konfigurasi ujian 11 - sebagai hujah dalam kaedah ini kami lulus nama jadual yang kami perlukan, dan dia, sebagai pekerja keras yang bertanggungjawab, akan memuatkannya untuk kami (yang memberi kami peluang untuk menggunakan semula kaedah ini sesuka hati kita) 21 - kita menggunakan kaedah ini untuk pembersihan, iaitu, memadam semua jadual (dan datanya) daripada pangkalan data 27 - hujah dalam kaedah ini ialah susunan nama skrip dengan data ujian yang akan dimuatkan untuk menguji kaedah tertentu. Skrip kami dengan data ujian:
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')
Dan sekarang apa yang kita semua kumpulkan untuk hari ini.

Kelas ujian 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 - kami mewarisi daripada kelas utama untuk ujian kami 4 - repositori kami yang diuji 7 - kaedah yang akan dilancarkan sebelum setiap ujian 8 - kami menggunakan kaedah kelas induk untuk memuatkan jadual yang diperlukan 11 - kami memulakan dao 15 kami - kaedah yang akan dilancarkan selepas setiap ujian, membersihkan pangkalan data kami 19 - pelaksanaan RowMapper kami, sama dengan kelas Tao Kami menggunakan @Before dan @After, yang digunakan sebelum dan selepas satu kaedah ujian, tetapi kami boleh mengambil beberapa lib yang membolehkan kami untuk menggunakan anotasi yang terikat pada permulaan ujian pelaksanaan kelas ini dan penghujungnya. Contohnya, yang ini , yang akan mempercepatkan ujian dengan ketara, kerana jadual perlu dibuat dan dipadamkan sepenuhnya setiap kali, dan sekali setiap kelas. Tetapi kami tidak berbuat demikian. Kenapa awak tanya? Bagaimana jika salah satu kaedah mengubah struktur jadual? Sebagai contoh, padam satu lajur. Dalam kes ini, kaedah yang selebihnya mungkin gagal atau mesti bertindak balas seperti yang diharapkan (contohnya, buat lajur belakang). Kita harus mengakui bahawa ini memberi kita sambungan (pergantungan) ujian yang tidak perlu antara satu sama lain, yang tidak berguna kepada kita. Tetapi saya menyimpang, mari kita teruskan...

Menguji kaedah 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 - isi jadual dengan data ujian 5 - dapatkan id untuk entiti yang kita perlukan 6 - gunakan kaedah yang diuji 8...12 - bandingkan data yang diterima dengan yang dijangkakan

Kemas kini ujian kaedah

@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 - isi jadual dengan data ujian 5 - dapatkan id entiti yang sedang dikemas kini 7 - bina entiti yang dikemas kini 14 - gunakan kaedah yang diuji 15 - dapatkan entiti yang dikemas kini untuk pengesahan 20...28 - bandingkan data yang diterima dengan yang dijangka Menguji kaedah kemas kini adalah serupa dengan mencipta. Sekurang-kurangnya untuk saya. Anda boleh memutar belit penyelarasan sesuka hati: tidak boleh ada terlalu banyak pemeriksaan. Saya juga ingin ambil perhatian bahawa ujian tidak menjamin kefungsian penuh atau ketiadaan pepijat. Ujian hanya memastikan bahawa hasil sebenar program (serpihannya) sepadan dengan yang diharapkan. Dalam kes ini, hanya bahagian yang ujian ditulis diperiksa.

Mari kita lancarkan kelas dengan ujian...

Ujian integrasi pangkalan data menggunakan MariaDB untuk menggantikan MySql - 7Kemenangan)) Mari kita buat teh dan dapatkan biskut: kita layak mendapatnya)) Ujian integrasi pangkalan data menggunakan MariaDB untuk menggantikan MySql - 8

pautan yang berguna

Bagi yang telah selesai membaca, terima kasih atas perhatian dan... Ujian integrasi pangkalan data menggunakan MariaDB untuk menggantikan MySql - 9

*muzik Star Wars epik*

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