JavaRush /Блоги Java /Random-TG /Биёед намунаи фармонро барои кор бо бот амалӣ кунем. (Қис...
Roman Beekeeper
Сатҳи

Биёед намунаи фармонро барои кор бо бот амалӣ кунем. (Қисми 2) - "Лоиҳаи Java аз А то Я"

Дар гурӯҳ нашр шудааст

Мо барои барнома санҷишҳо менависем

Оғози мақола: навиштани JRTB-3 . Ҳоло мо бояд дар бораи санҷиш фикр кунем. Ҳама рамзи иловашуда бояд бо санҷишҳо фаро гирифта шаванд, то боварӣ ҳосил кунем, ки функсия тавре ки мо интизор будем, кор мекунад. Аввалан мо барои хидмати SendBotMessageService санҷишҳои воҳидҳо менависем.
Санҷиши воҳид санҷишест, ки мантиқи баъзе қисми хурди барномаро месанҷад: одатан ин усулҳо мебошанд. Ва ҳама пайвастагиҳое, ки ин усул доранд, бо истифода аз масхара бо пайвандҳои қалбакӣ иваз карда мешаванд.
Акнун шумо ҳама чизро хоҳед дид. Дар ҳамон баста, танҳо дар ҷузвдони ./src/test/java , мо синферо бо ҳамон ном бо синфе, ки озмоиш хоҳем кард, эҷод мекунем ва дар охир Test илова мекунем . Яъне барои SendBotMessageService мо SendBotMessageServiceTest дорем , ки ҳамаи санҷишҳоро барои ин синф дар бар мегирад. Идеяи санҷиши он чунин аст: мо JavaRushTelegarmBot-и масхара (қалбакӣ) мезанем, ки баъд аз он мепурсем, ки оё усули иҷро бо чунин далел даъват шудааст ё не. Ин аст он чизе ки рӯй дод:
package com.github.javarushcommunity.jrtb.service;

import com.github.javarushcommunity.jrtb.bot.JavarushTelegramBot;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;

@DisplayName("Unit-level testing for SendBotMessageService")
public class SendBotMessageServiceTest {

   private SendBotMessageService sendBotMessageService;
   private JavarushTelegramBot javarushBot;

   @BeforeEach
   public void init() {
       javarushBot = Mockito.mock(JavarushTelegramBot.class);
       sendBotMessageService = new SendBotMessageServiceImpl(javarushBot);
   }

   @Test
   public void shouldProperlySendMessage() throws TelegramApiException {
       //given
       String chatId = "test_chat_id";
       String message = "test_message";

       SendMessage sendMessage = new SendMessage();
       sendMessage.setText(message);
       sendMessage.setChatId(chatId);
       sendMessage.enableHtml(true);

       //when
       sendBotMessageService.sendMessage(chatId, message);

       //then
       Mockito.verify(javarushBot).execute(sendMessage);
   }
}
Бо истифода аз Mockito, ман an objectи масхаракунандаи JavaRushBot сохтам, ки онро ба созандаи хидмати мо додам. Баъдан, ман як санҷиш навиштам (ҳар як усул бо шарҳи Тест санҷиши алоҳида аст). Сохтори ин усул ҳамеша якхела аст - он далелҳо намегирад ва беэътиборро бармегардонад. Номи санҷиш бояд ба шумо бигӯяд, ки мо чиро санҷида истодаем. Дар ҳолати мо, ин аст: бояд паёмро дуруст фиристад - бояд паёмро дуруст фиристад. Санҷиши мо ба се қисм тақсим мешавад:
  • блок // дода шудааст - дар он ҷо мо ҳама чизро барои санҷиш омода мекунем;
  • блок // кай - он ҷое ки мо усулеро оғоз мекунем, ки мо озмоишро ба нақша гирифтаем;
  • //пас блок - дар он ҷо мо тафтиш мекунем, ки оё усул дуруст кор кардааст.
Азбаски мантиқи хидмати мо то ҳол оддӣ аст, як санҷиш барои ин синф кифоя хоҳад буд. Акнун биёед барои CommandContainer санҷиш нависед:
package com.github.javarushcommunity.jrtb.command;

import com.github.javarushcommunity.jrtb.service.SendBotMessageService;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import java.util.Arrays;

@DisplayName("Unit-level testing for CommandContainer")
class CommandContainerTest {

   private CommandContainer commandContainer;

   @BeforeEach
   public void init() {
       SendBotMessageService sendBotMessageService = Mockito.mock(SendBotMessageService.class);
       commandContainer = new CommandContainer(sendBotMessageService);
   }

   @Test
   public void shouldGetAllTheExistingCommands() {
       //when-then
       Arrays.stream(CommandName.values())
               .forEach(commandName -> {
                   Command command = commandContainer.retrieveCommand(commandName.getCommandName());
                   Assertions.assertNotEquals(UnknownCommand.class, command.getClass());
               });
   }

   @Test
   public void shouldReturnUnknownCommand() {
       //given
       String unknownCommand = "/fgjhdfgdfg";

       //when
       Command command = commandContainer.retrieveCommand(unknownCommand);

       //then
       Assertions.assertEquals(UnknownCommand.class, command.getClass());
   }
}
Ин як санҷиши хеле равшан нест. Он ба мантиқи контейнер такя мекунад. Ҳама фармонҳое, ки бот дастгирӣ мекунад, дар рӯйхати CommandName ҳастанд ва бояд дар контейнер бошанд. Ҳамин тавр, ман ҳама тағирёбандаҳои CommandName-ро гирифтам, ба Stream API рафтам ва барои ҳар яке аз контейнер фармонро ҷустуҷӯ кардам. Агар чунин фармон намебуд, Фармони номаълум баргардонида мешавад. Ин аст он чизе ки мо дар ин сатр тафтиш мекунем:
Assertions.assertNotEquals(UnknownCommand.class, command.getClass());
Ва барои санҷидани он, ки UnknownCommand пешфарз хоҳад буд, ба шумо санҷиши алоҳида лозим аст - shouldReturnUnknownCommand . Ман ба шумо маслиҳат медиҳам, ки ин санҷишҳоро аз нав нависед ва таҳлил кунед. Ҳоло барои дастаҳо санҷишҳои нимрасмӣ хоҳанд буд, аммо онҳо бояд навишта шаванд. Мантиқ бо озмоиши SendBotMessageService якхела хоҳад буд, аз ин рӯ ман мантиқи умумии санҷишро ба синфи AbstractCommandTest интиқол медиҳам ва ҳар як синфи мушаххаси тестӣ мерос гирифта, майдонҳои заруриро муайян мекунад. Азбаски ҳама санҷишҳо як навъанд, ҳар дафъа навиштани як чиз осон нест, илова бар ин, ин нишонаи рамзи хуб нест. Ин аст, ки синфи абстрактии умумӣ чунин ба вуҷуд омад:
package com.github.javarushcommunity.jrtb.command;

import com.github.javarushcommunity.jrtb.bot.JavarushTelegramBot;
import com.github.javarushcommunity.jrtb.service.SendBotMessageService;
import com.github.javarushcommunity.jrtb.service.SendBotMessageServiceImpl;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.mockito.internal.verification.VerificationModeFactory;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.objects.Message;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;

/**
* Abstract class for testing {@link Command}s.
*/
abstract class AbstractCommandTest {

   protected JavarushTelegramBot javarushBot = Mockito.mock(JavarushTelegramBot.class);
   protected SendBotMessageService sendBotMessageService = new SendBotMessageServiceImpl(javarushBot);

   abstract String getCommandName();

   abstract String getCommandMessage();

   abstract Command getCommand();

   @Test
   public void shouldProperlyExecuteCommand() throws TelegramApiException {
       //given
       Long chatId = 1234567824356L;

       Update update = new Update();
       Message message = Mockito.mock(Message.class);
       Mockito.when(message.getChatId()).thenReturn(chatId);
       Mockito.when(message.getText()).thenReturn(getCommandName());
       update.setMessage(message);

       SendMessage sendMessage = new SendMessage();
       sendMessage.setChatId(chatId.toString());
       sendMessage.setText(getCommandMessage());
       sendMessage.enableHtml(true);

       //when
       getCommand().execute(update);

       //then
       Mockito.verify(javarushBot).execute(sendMessage);
   }
}
Тавре ки шумо мебинед, мо се усули абстрактӣ дорем, ки пас аз муайян кардани он, ки ҳар як фармон бояд санҷиши дар ин ҷо навишташударо иҷро кунад ва дуруст иҷро кунад. Ин чунин як равиши мувофиқ аст, вақте ки мантиқи асосӣ дар синфи абстрактӣ аст, аммо ҷузъиёт дар наслҳо муайян карда мешаванд. Ва дар ин ҷо, дар асл, татбиқи санҷишҳои мушаххас мавҷуданд:

HelpCommandTest:

package com.github.javarushcommunity.jrtb.command;

import org.junit.jupiter.api.DisplayName;

import static com.github.javarushcommunity.jrtb.command.CommandName.HELP;
import static com.github.javarushcommunity.jrtb.command.HelpCommand.HELP_MESSAGE;

@DisplayName("Unit-level testing for HelpCommand")
public class HelpCommandTest extends AbstractCommandTest {

   @Override
   String getCommandName() {
       return HELP.getCommandName();
   }

   @Override
   String getCommandMessage() {
       return HELP_MESSAGE;
   }

   @Override
   Command getCommand() {
       return new HelpCommand(sendBotMessageService);
   }
}

NoCommandTest:

package com.github.javarushcommunity.jrtb.command;

import org.junit.jupiter.api.DisplayName;

import static com.github.javarushcommunity.jrtb.command.CommandName.NO;
import static com.github.javarushcommunity.jrtb.command.NoCommand.NO_MESSAGE;

@DisplayName("Unit-level testing for NoCommand")
public class NoCommandTest extends AbstractCommandTest {

   @Override
   String getCommandName() {
       return NO.getCommandName();
   }

   @Override
   String getCommandMessage() {
       return NO_MESSAGE;
   }

   @Override
   Command getCommand() {
       return new NoCommand(sendBotMessageService);
   }
}

StartCommandTest:

package com.github.javarushcommunity.jrtb.command;

import org.junit.jupiter.api.DisplayName;

import static com.github.javarushcommunity.jrtb.command.CommandName.START;
import static com.github.javarushcommunity.jrtb.command.StartCommand.START_MESSAGE;

@DisplayName("Unit-level testing for StartCommand")
class StartCommandTest extends AbstractCommandTest {

   @Override
   String getCommandName() {
       return START.getCommandName();
   }

   @Override
   String getCommandMessage() {
       return START_MESSAGE;
   }

   @Override
   Command getCommand() {
       return new StartCommand(sendBotMessageService);
   }
}

StopCommandTest:

package com.github.javarushcommunity.jrtb.command;

import org.junit.jupiter.api.DisplayName;

import static com.github.javarushcommunity.jrtb.command.CommandName.STOP;
import static com.github.javarushcommunity.jrtb.command.StopCommand.STOP_MESSAGE;

@DisplayName("Unit-level testing for StopCommand")
public class StopCommandTest extends AbstractCommandTest {

   @Override
   String getCommandName() {
       return STOP.getCommandName();
   }

   @Override
   String getCommandMessage() {
       return STOP_MESSAGE;
   }

   @Override
   Command getCommand() {
       return new StopCommand(sendBotMessageService);
   }
}

Санҷиши фармони номаълум:

package com.github.javarushcommunity.jrtb.command;

import org.junit.jupiter.api.DisplayName;

import static com.github.javarushcommunity.jrtb.command.UnknownCommand.UNKNOWN_MESSAGE;

@DisplayName("Unit-level testing for UnknownCommand")
public class UnknownCommandTest extends AbstractCommandTest {

   @Override
   String getCommandName() {
       return "/fdgdfgdfgdbd";
   }

   @Override
   String getCommandMessage() {
       return UNKNOWN_MESSAGE;
   }

   @Override
   Command getCommand() {
       return new UnknownCommand(sendBotMessageService);
   }
}
Равшан аст, ки бозӣ ба шамъ меарзад ва ба шарофати AbstractCommandTest мо бо санҷишҳои оддӣ ва фаҳмо ба анҷом расидем, ки навиштан ва фаҳмидан осон аст. Илова бар ин, мо аз такрори codeҳои нолозим халос шудем (салом ба DRY -> Принсипи Худро такрор накунед). Илова бар ин, ҳоло мо санҷишҳои воқеӣ дорем, ки тавассути онҳо мо метавонем иҷрои барномаро доварӣ кунем. Инчунин хуб мебуд, ки барои худи бот санҷиш нависед, аммо ҳама чиз ба осонӣ ва умуман кор намекунад, шояд бозӣ ба шамъ намеарзад, чунон ки мегӯянд. Бинобар ин, дар ин марҳила мо вазифаи худро анҷом медиҳем. Чизи охирин ва дӯстдошта - мо ӯҳдадор мешавем, менависад паём: JRTB-3: Намунаи фармони иловашуда барои коркарди фармонҳои Telegram Bot Ва чун маъмул - Github аллакай медонад ва пешниҳод мекунад, ки дархости кашиданро эҷод кунад: "Лоиҳаи Java аз A то Я": Амалисозии намунаи фармон барои кор бо бот.  Қисми 2 - 1Сохтмон гузашт ва шумо аллакай метавонед. якҷоя... Аммо не! Ман фаромӯш кардам, ки versionи лоиҳаро навсозӣ кунам ва онро дар RELEASE_NOTES нависед. Мо як вурудро бо versionи нав илова мекунем - 0.2.0-SNAPSHOT: "Лоиҳаи Java аз A то Я": Амалисозии намунаи фармон барои кор бо бот.  Қисми 2 - 2Мо ин versionро дар pom.xml навсозӣ мекунем ва ӯҳдадории нав эҷод мекунем: Уҳдадории "Лоиҳаи Java аз A то Я": Амалисозии намунаи фармон барои кор бо бот.  Қисми 2 - 3нав: JRTB-3: навсозӣ RELEASE_NOTES.md"Лоиҳаи Java аз A то Я": Амалисозии намунаи фармон барои кор бо бот.  Қисми 2 - 4 Акнун пахш кунед ва интизор шавед, ки сохтмон ба итмом расад. Сохтмон гузашт, шумо метавонед онро якҷоя кунед: "Java-проект от А до Я": Реализуем Command Pattern для работы с ботом. Часть 2 - 5Ман фorалро нест намекунам, бинобар ин шумо ҳамеша метавонед дида бароед ва муқоиса кунед, ки чӣ тағир ёфтааст. Шӯрои вазифаҳои мо нав карда шуд:"Java-проект от А до Я": Реализуем Command Pattern для работы с ботом. Часть 2 - 6

хулосахо

Имрӯз мо як кори бузургро анҷом додем: мо қолаби Фармонро барои кор ҷорӣ кардем. Ҳама чиз танзим шудааст ва ҳоло илова кардани як дастаи нав як раванди содда ва осон хоҳад буд. Мо имрӯз дар бораи санҷиш низ сӯҳбат кардем. Мо ҳатто каме бо такрор накардани рамз дар санҷишҳои гуногун барои дастаҳо бозӣ кардем. Мисли маъмул, ман пешниҳод мекунам, ки дар GitHub сабти ном шавам ва ҳисоби худро пайгирӣ кунам , то ин силсила ва дигар лоиҳаҳоеро, ки дар он ҷо кор карда истодаам, пайгирӣ кунам. Ман инчунин як канали телеграмм таъсис додам , ки дар он нашри мақолаҳои навро такрор мекунам. Як чизи ҷолиб он аст, ки code одатан як ҳафта пеш аз худи мақола бароварда мешавад ва дар канал ман ҳар боре, ки вазифаи нав иҷро шудааст, менависам, ки ин ба ман имкон медиҳад, ки пеш аз хондани мақола рамзро бифаҳмам. Ба наздикӣ ман ботро ба таври доимӣ нашр хоҳам кард ва онҳое, ки ба канали телеграм обуна мешаванд, аввалин шуда аз он огоҳ мешаванд;) Ташаккур ба ҳама барои хондан, идома дорад.

Рӯйхати ҳамаи маводҳои силсила дар аввали ин мақола аст.

Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION