JavaRush /Java Blog /Random-TL /Pagsubok sa pagsasama ng isang database gamit ang MariaDB...

Pagsubok sa pagsasama ng isang database gamit ang MariaDB upang palitan ang MySql

Nai-publish sa grupo
Pagsubok sa pagsasama ng isang database gamit ang MariaDB upang palitan ang MySql - 1Ngayon nais kong pag-usapan ang tungkol sa pagsubok, dahil mas natatakpan ng mga pagsubok ang code, mas mahusay at mas maaasahan ito ay isinasaalang-alang. Pag-usapan natin hindi ang tungkol sa unit testing, ngunit tungkol sa integration testing ng mga database. Ano nga ba ang pagkakaiba sa pagitan ng mga unit test at integration test? Pagsubok sa pagsasama ng isang database gamit ang MariaDB upang palitan ang MySql - 2Ang Modular (unit) ay sumusubok sa isang programa sa antas ng mga indibidwal na module, pamamaraan o klase, iyon ay, ang mga pagsubok ay mabilis at madali, na nakakaapekto sa mga pinaka-nahihiwalay na bahagi ng pag-andar. Ang mga ito ay tinutukoy din bilang "isang pagsubok sa bawat pamamaraan". Ang mga pagsasama ay mas mabagal at mas mabigat, at maaaring binubuo ng ilang mga module at karagdagang pag-andar. Pagsubok sa pagsasama ng isang database gamit ang MariaDB upang palitan ang MySql - 3Bakit ang mga pagsubok para sa dao (Data Access Object) na mga pagsubok sa pagsasama ng layer? Dahil upang subukan ang mga pamamaraan na may mga query sa database, kailangan nating itaas ang isang hiwalay na database sa RAM, palitan ang pangunahing isa. Ang ideya ay gumawa kami ng mga talahanayan na kailangan namin, punan ang mga ito ng data ng pagsubok at suriin ang kawastuhan ng mga pamamaraan ng klase ng repositoryo (pagkatapos ng lahat, alam namin kung ano ang dapat na huling resulta sa isang partikular na kaso). Kaya, magsimula tayo. Ang mga paksa sa pagkonekta ng isang database ay matagal nang sakop sa malayo, at samakatuwid ngayon ay hindi ko nais na pag-isipan ito, at isasaalang-alang lamang namin ang mga bahagi ng programa na interesado sa amin. Bilang default, magsisimula kami sa katotohanan na ang aming aplikasyon ay batay sa Spring Boot, para sa Spring JDBC dao layer (para sa higit na kalinawan), ang aming pangunahing database ay MySQL, at papalitan namin ito gamit ang MariaDB (ang mga ito ay lubos na katugma, at naaayon, ang mga script ng MySQL ay hindi kailanman magkakaroon ng mga salungatan sa MariaDB dialect, tulad ng magkakaroon sa H2). May kondisyon din kaming ipagpalagay na ang aming programa ay gumagamit ng Liquibase upang pamahalaan at ilapat ang mga pagbabago sa schema ng database, at nang naaayon, lahat ng inilapat na script ay naka-imbak sa aming aplikasyon.

Istraktura ng proyekto

Ang mga apektadong bahagi lamang ang ipinapakita: Pagsubok sa pagsasama ng isang database gamit ang MariaDB upang palitan ang MySql - 5At oo, ngayon ay gagawa tayo ng mga robot)) Pagsubok sa pagsasama ng isang database gamit ang MariaDB upang palitan ang MySql - 6Script para sa talahanayan, ang mga pamamaraan kung saan susuriin natin ngayon (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;
Ang entity na kumakatawan sa talahanayang ito:
@Builder
@Data
public class Robot {

   private Long id;

   private String name;

   private String cpu;

   private String producer;
}
Interface para sa nasubok na imbakan:
public interface RobotDAO {

   Robot findById(Long id);

   Robot create(Robot robot);

   List<Robot> findAll();

   Robot update(Robot robot);

   void delete(Long id);
}
Sa totoo lang, narito ang mga karaniwang operasyon ng CRUD, nang walang mga exotics, kaya isasaalang-alang namin ang pagpapatupad ng hindi lahat ng mga pamamaraan (mabuti, hindi ito magugulat sa sinuman), ngunit ang ilan - para sa mas maikli:
@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();
   }
Magsagawa tayo ng kaunting digression at tingnan kung ano ang nangyayari sa ating mga dependency (tanging ang mga ginamit para sa ipinakitang bahagi ng application ang ipinakita):
<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 - dependency para sa MariaDb database mismo 10 - dependency para sa pagkonekta sa SpringBoot 16 - Lombok (well, sa palagay ko alam ng lahat kung anong uri ng lib ito) 22 - starter para sa mga pagsubok (kung saan ang JUnit na kailangan natin ay naka-embed) 28 - starter para sa nagtatrabaho sa springJdbc Tingnan natin ang lalagyan ng tagsibol na may mga beans na kailangan para sa aming mga pagsubok (lalo na, ang MariaDB creation bean):
@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 - ang pangunahing bahagi para sa pagpapalaki ng MariaDB (para sa mga application batay sa Spring Framework) 10 - pagtukoy ng isang database bean 12 - pagtatakda ng pangalan ng nilikhang Database 17 - pagbubunot ng mga configuration para sa aming kaso 19 - pagbuo ng database gamit ang Builder pattern ( isang magandang pangkalahatang-ideya ng pattern ) At sa wakas, ang pinagkakaabalahan ay ang JdbcTemplate bean para sa komunikasyon sa database na itinataas. Ang ideya ay magkakaroon tayo ng pangunahing klase para sa mga pagsubok sa Tao, kung saan ang lahat ng klase ng pagsubok sa Tao ay magmamana, na ang mga gawain ay kinabibilangan ng:
  1. paglulunsad ng ilang mga script na ginamit sa pangunahing database (mga script para sa paglikha ng mga talahanayan, pagbabago ng mga haligi, at iba pa);
  2. paglulunsad ng mga test script na pumupuno sa mga talahanayan ng data ng pagsubok;
  3. pagtanggal ng mga talahanayan.
@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 - gamit ang @SpringBootTest annotation nagtatakda kami ng configuration ng pagsubok 11 - bilang argumento sa paraang ito ipinapasa namin ang mga pangalan ng mga talahanayan na kailangan namin, at siya, bilang isang responsableng masipag na manggagawa, ay maglo-load ng mga ito para sa amin (na nagbibigay sa amin ng pagkakataon upang muling gamitin ang pamamaraang ito hangga't nais ng ating puso) 21 - ginagamit natin ang pamamaraang ito para sa paglilinis, ibig sabihin, pagtanggal ng lahat ng mga talahanayan (at ang kanilang data) mula sa database 27 - ang argumento sa pamamaraang ito ay isang hanay ng mga pangalan ng mga script na may data ng pagsubok na ilo-load para sa pagsubok ng isang partikular na pamamaraan. Ang aming script na may data ng pagsubok:
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')
At ngayon kung ano ang natipon nating lahat para sa araw na ito.

Tao testing class

@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 - nagmana kami mula sa pangunahing klase para sa aming mga pagsubok 4 - ang aming nasubok na imbakan 7 - isang pamamaraan na ilulunsad bago ang bawat pagsubok 8 - ginagamit namin ang paraan ng klase ng magulang upang i-load ang mga kinakailangang talahanayan 11 - sinisimulan namin ang aming dao 15 - isang pamamaraan na ilulunsad pagkatapos ng bawat pagsubok, paglilinis ng aming database 19 - pagpapatupad ng aming RowMapper, kahalintulad sa klase ng Tao Ginagamit namin ang @Before at @After, na ginagamit bago at pagkatapos ng isang paraan ng pagsubok, ngunit maaari kaming kumuha ng ilang lib na nagpapahintulot sa amin na gumamit ng mga anotasyon na nauugnay sa simula ng mga pagsusulit sa pagpapatupad ng klase na ito at sa pagtatapos. Halimbawa, ang isang ito , na makabuluhang magpapabilis sa mga pagsubok, dahil ang mga talahanayan ay kailangang gawin at ganap na tanggalin sa bawat oras, at isang beses bawat klase. Pero hindi namin ginagawa yun. Bakit mo natanong? Paano kung binago ng isa sa mga pamamaraan ang istraktura ng talahanayan? Halimbawa, tanggalin ang isang column. Sa kasong ito, ang natitirang mga pamamaraan ay maaaring mabigo o dapat tumugon gaya ng inaasahan (halimbawa, gumawa ng back column). Dapat nating aminin na nagbibigay ito sa atin ng hindi kinakailangang koneksyon (dependence) ng mga pagsubok sa isa't isa, na walang silbi sa atin. Ngunit lumihis ako, magpatuloy tayo...

Pagsubok sa paraan ng 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 - punan ang talahanayan ng data ng pagsubok 5 - kunin ang id para sa entity na kailangan namin 6 - gamitin ang pamamaraang sinusuri 8...12 - ihambing ang natanggap na data sa mga inaasahan

I-update ang paraan ng pagsubok

@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 - punan ang talahanayan ng data ng pagsubok 5 - kunin ang id ng entity na ina-update 7 - buuin ang na-update na entity 14 - gamitin ang paraan na sinusuri 15 - kunin ang na-update na entity para sa pag-verify 20...28 - ihambing ang natanggap na data sa ang mga inaasahang Pagsubok sa paraan ng pag-update ay katulad ng paglikha. Kahit papaano para sa akin. Maaari mong i-twist ang mga pagkakasundo hangga't gusto mo: hindi kailanman maaaring magkaroon ng masyadong maraming mga tseke. Gusto ko ring tandaan na ang mga pagsubok ay hindi ginagarantiyahan ang buong pag-andar o ang kawalan ng mga bug. Tinitiyak lamang ng mga pagsubok na ang aktwal na resulta ng programa (ang fragment nito) ay tumutugma sa inaasahan. Sa kasong ito, ang mga bahagi lamang kung saan isinulat ang mga pagsusulit ang sinusuri.

Maglunsad tayo ng isang klase na may mga pagsubok...

Pagsubok sa pagsasama ng isang database gamit ang MariaDB upang palitan ang MySql - 7Tagumpay)) Gumawa tayo ng tsaa at kumuha ng cookies: karapat-dapat tayo)) Pagsubok sa pagsasama ng isang database gamit ang MariaDB upang palitan ang MySql - 8

kapaki-pakinabang na mga link

Para sa mga nakatapos ng pagbabasa, salamat sa inyong atensyon at... Pagsubok sa pagsasama ng isang database gamit ang MariaDB upang palitan ang MySql - 9

*epic Star Wars music*

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