JavaRush /Java блогы /Random-KK /MySql ауыстыру үшін MariaDB көмегімен дерекқорды интеграц...
Константин
Деңгей

MySql ауыстыру үшін MariaDB көмегімен дерекқорды интеграциялық тестілеу

Топта жарияланған
MySql - 1 ауыстыру үшін MariaDB көмегімен дерекқорды интеграциялық тестілеуБүгін мен тестілеу туралы айтқым келеді, өйткені code тесттермен неғұрлым көп қамтылса, соғұрлым ол жақсырақ және сенімдірек деп саналады. Бірлік тестілеу туралы емес, деректер қорын интеграциялық тестілеу туралы сөйлесейік. Бірлік сынақтары мен интеграциялық сынақтардың нақты айырмашылығы неде? MySql - 2 ауыстыру үшін MariaDB көмегімен деректер қорын интеграциялық тестілеуМодульдік (бірлік) - бұл бағдарламаны жеке модульдер, әдістер немесе сыныптар деңгейінде тестілеу, яғни тесттер функционалдылықтың ең бөлінетін бөліктеріне әсер ететін жылдам және оңай. Олар сондай-ақ «әр әдіске бір сынақ» деп аталады. Интеграциялар баяу және ауырырақ және бірнеше модульдерден және қосымша функциялардан тұруы мүмкін. MySql - 3 ауыстыру үшін MariaDB көмегімен деректер қорын интеграциялық тестілеуНеліктен dao (Data Access Object) деңгейіне арналған сынақтар біріктіру сынақтары болып табылады? Өйткені мәліметтер базасына сұраныстары бар әдістерді сынау үшін біз негізгісін ауыстыра отырып, жедел жадта жеке мәліметтер қорын көтеруіміз керек. Идея мынада: біз өзімізге қажетті кестелерді жасаймыз, оларды сынақ деректерімен толтырамыз және репозиторий класс әдістерінің дұрыстығын тексереміз (ақыр соңында, біз белгілі бір жағдайда соңғы нәтиже қандай болуы керек екенін білеміз). Сонымен, бастайық. Мәліметтер қорын қосу тақырыптары бұрыннан бері қарастырылған, сондықтан мен бүгін бұл туралы тоқталғым келмейді және біз бағдарламаның бізді қызықтыратын бөліктерін ғана қарастырамыз. Әдепкі бойынша, біз қосымшаның Spring Boot-қа негізделгенінен бастаймыз, Spring JDBC dao қабаты үшін (анық болу үшін), біздің негізгі дерекқорымыз MySQL болып табылады және біз оны MariaDB арқылы ауыстырамыз (олар барынша үйлесімді және сәйкес MySQL сценарийлері ешқашан MariaDB диалектімен қайшылықтар болмайды, өйткені H2-де болады). Сондай-ақ біз шартты түрде бағдарламамыз дерекқор схемасына өзгертулерді басқару және қолдану үшін Liquibase пайдаланады деп есептейміз және сәйкесінше барлық қолданбалы сценарийлер біздің қолданбада сақталады.

Жоба құрылымы

Тек зардап шеккен бөліктер көрсетіледі: MySql - 5 ауыстыру үшін MariaDB көмегімен деректер базасын интеграциялық тестілеуИә, бүгін біз роботтарды жасаймыз)) MySql - 6 ауыстыру үшін MariaDB көмегімен деректер қорын интеграциялық тестілеуКестеге арналған сценарий, біз бүгін сынайтын әдістер (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;
Осы кестені көрсететін нысан:
@Builder
@Data
public class Robot {

   private Long id;

   private String name;

   private String cpu;

   private String producer;
}
Тексерілген репозиторийге арналған интерфейс:
public interface RobotDAO {

   Robot findById(Long id);

   Robot create(Robot robot);

   List<Robot> findAll();

   Robot update(Robot robot);

   void delete(Long id);
}
Шын мәнінде, мұнда экзотикасыз стандартты CRUD операциялары бар, сондықтан біз барлық әдістерді емес (жақсы, бұл ешкімді таң қалдырмайды), бірақ кейбіреулерін қысқарту үшін қарастырамыз:
@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();
   }
Кішкене шегініс жасап, тәуелділіктерімізбен не болып жатқанын көрейік (қолданбаның көрсетілген бөлігі үшін ғана қолданылатындар ұсынылған):
<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 - MariaDb дерекқорының өзіне тәуелділік 10 - SpringBoot 16-ға қосылуға тәуелділік - Lombok (бұл қандай lib екенін бәрі біледі деп ойлаймын) 22 - сынақтарға арналған стартер (бізге қажет JUnit ендірілген жерде) 28 - стартер springJdbc-пен жұмыс істеу Біздің сынақтарымызға қажет бұршақтары бар көктемгі контейнерді қарастырайық (атап айтқанда, 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 - MariaDB-ны көтеруге арналған негізгі компонент (Spring Framework негізіндегі қолданбалар үшін) 10 - деректер қорын анықтау 12 - құрылған Дерекқордың атын орнату 17 - біздің жағдайымыз үшін конфигурацияларды шығару 19 - Builder үлгісін пайдаланып деректер базасын құру ( Үлгіге жақсы шолу ) Және, ақырында, барлық әбігерге түсетін нәрсе - JdbcTemplate бұршағындағы дерекқормен байланыс орнату. Идея мынада: бізде Дао сынақтары үшін негізгі сынып болады, одан барлық Дао сынақ сыныптары мұрагер болады, оның міндеттеріне мыналар кіреді:
  1. негізгі дерекқорда қолданылатын кейбір сценарийлерді іске қосу (кестелерді құру, бағандарды өзгерту және т.б. сценарийлер);
  2. кестелерді тест деректерімен толтыратын тест сценарийлерін іске қосу;
  3. кестелерді жою.
@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 - @SpringBootTest annotationсын қолдана отырып, біз сынақ конфигурациясын орнаттық 11 - бұл әдісте дәлел ретінде біз қажетті кестелердің атауларын береміз және ол жауапты еңбекқор қызметкер ретінде оларды біз үшін жүктейді (бұл бізге мүмкіндік береді бұл әдісті жүрегіміз қалағанша қайта пайдалану) 21 - біз бұл әдісті тазалау үшін қолданамыз, атап айтқанда, деректер базасынан барлық кестелерді (және олардың деректерін) жою 27 - бұл әдістегі аргумент сынақ деректері бар сценарийлер атауларының массиві болып табылады. ол белгілі бір әдісті сынау үшін жүктеледі. Сынақ деректері бар біздің сценарий:
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')
Ал енді бүгін барлығымыз нені жинадық.

Дао тестілеу сабағы

@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 - біз сынақтар үшін негізгі сыныптан мұра аламыз 4 - сынақтан өткен репозиторийіміз 7 - әрбір сынақ алдында іске қосылатын әдіс 8 - қажетті кестелерді жүктеу үшін ата-аналық сынып әдісін қолданамыз 11 - дао 15 - әдісті инициализациялаймыз ол әрбір сынақтан кейін іске қосылады, біздің дерекқорымызды тазартады 19 - RowMapper-ді іске асыру, Tao класына ұқсас Біз @Before және @After пайдаланамыз, олар бір сынақ әдісіне дейін және кейін пайдаланылады, бірақ бізге мүмкіндік беретін кейбір lib-ті алуға болады. осы сыныптың орындалу сынақтарының басына және соңына байланысты annotationларды пайдалану. Мысалы, бұл сынақтарды айтарлықтай жылдамдатады, өйткені кестелер әр уақытта және әр сыныпта бір рет жасалып, толығымен жойылуы керек еді. Бірақ біз мұны істемейміз. Сен неге сұрайсың? Егер әдістердің бірі кестенің құрылымын өзгертсе ше? Мысалы, бір бағанды ​​жойыңыз. Бұл жағдайда қалған әдістер сәтсіз болуы мүмкін немесе күткендей жауап беруі керек (мысалы, артқы баған жасаңыз). Бұл бізге сынақтардың бір-біріне қажетсіз байланысын (тәуелділігін) беретінін мойындауымыз керек, бұл бізге пайдасы жоқ. Бірақ мен шегінемін, әрі қарай жалғастырайық...

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 - кестені сынақ деректерімен толтыру 5 - бізге қажет нысанның идентификаторын алу 6 - тексерілетін әдісті қолдану 8...12 - алынған мәліметтерді күтілгендермен салыстыру

Жаңарту әдісі тесті

@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 - кестені сынақ деректерімен толтыру 5 - жаңартылатын нысанның идентификаторын алу 7 - жаңартылған нысанды құру 14 - тексерілетін әдісті пайдалану 15 - тексеру үшін жаңартылған нысанды алу 20...28 - алынған деректерді күтілетіндер Жаңарту әдісін сынау жасау әдісіне ұқсас. Кем дегенде мен үшін. Сәйкестендірулерді қалағаныңызша бұра аласыз: ешқашан тым көп тексерулер болмайды. Сондай-ақ, сынақтар толық функционалдылыққа немесе қателердің болмауына кепілдік бермейтінін атап өткім келеді. Тесттер тек бағдарламаның нақты нәтижесінің (оның фрагменті) күтілетін нәтижеге сәйкес келетінін ғана қамтамасыз етеді. Бұл жағдайда сынақтар жазылған бөліктер ғана тексеріледі.

Сабақты тесттерден бастайық...

MySql - 7 ауыстыру үшін MariaDB көмегімен деректер қорын интеграциялық тестілеуЖеңіс)) Шай қайнатып печенье алайық: біз оған лайықпыз)) MySql - 8 ауыстыру үшін MariaDB көмегімен дерекқорды интеграциялық тестілеу

пайдалы сілтемелер

Оқып болғандар үшін, назарларыңызға рахмет және... MySql - 9 ауыстыру үшін MariaDB көмегімен деректер қорын интеграциялық тестілеу

*жұлдызды соғыстардың эпикалық музыкасы*

Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION