JavaRush /جاوا بلاگ /Random-SD /اچو ته bot سان ڪم ڪرڻ لاءِ ڪمانڊ جو نمونو لاڳو ڪريون. (حص...

اچو ته bot سان ڪم ڪرڻ لاءِ ڪمانڊ جو نمونو لاڳو ڪريون. (حصو 2) - "جاوا پروجيڪٽ A کان Z تائين"

گروپ ۾ شايع ٿيل

اسان اپليڪيشن لاء ٽيسٽ لکندا آهيون

مضمون جي شروعات: لکڻ JRTB-3 . هاڻي اسان کي امتحان جي باري ۾ سوچڻ جي ضرورت آهي. سڀ شامل ڪيل ڪوڊ ٽيسٽن سان ڍڪيل هجن ته جيئن اسان پڪ ڪري سگهون ته ڪارڪردگي ڪم ڪري ٿي جيئن اسان جي توقع آهي. پهرين اسان SendBotMessageService سروس لاءِ يونٽ ٽيسٽ لکنداسين.
ھڪڙو يونٽ ٽيسٽ ھڪڙو امتحان آھي جيڪو ايپليڪيشن جي ڪجھ ننڍڙي حصي جي منطق کي جانچيندو آھي: عام طور تي اھي طريقا آھن. ۽ سڀئي ڪنيڪشن جيڪي هن طريقي سان آهن جعلي سان تبديل ڪيا ويا آهن ٺٺوليون استعمال ڪندي.
هاڻي توهان سڀ ڪجهه ڏسندا. ساڳئي پيڪيج ۾، صرف ./src/test/java فولڊر ۾ ، اسان هڪ ڪلاس ٺاهيندا آهيون ساڳئي نالي سان ڪلاس جنهن کي اسين آزمائينداسين، ۽ آخر ۾ ٽيسٽ شامل ڪريو . اهو آهي، 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 استعمال ڪندي، مون هڪ ٺٺولي 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 متغيرن کي ورتو، اسٽريم 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);
   }
}

اسٽاپ ڪمانڊ ٽيسٽ:

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 جي مهرباني، اسان سادي ۽ سمجھڻ واري ٽيسٽ سان ختم ڪيو جيڪي لکڻ ۾ آسان ۽ سمجهڻ ۾ آسان آهن. ان کان علاوه، اسان غير ضروري ڪوڊ جي نقل کان نجات حاصل ڪئي (هيلو کي DRY -> نه ورجايو پنهنجو اصول). ان کان علاوه، ھاڻي اسان وٽ حقيقي ٽيسٽ آھن جن جي ذريعي اسين ايپليڪيشن جي ڪارڪردگي جو اندازو لڳائي سگھون ٿا. اهو پڻ سٺو لڳندو ته بوٽ لاءِ هڪ ٽيسٽ لکڻ ، پر هر شيءِ ايتري آساني سان ڪم نه ڪندي ۽ عام طور تي ، ٿي سگهي ٿو ته راند موم بتي جي لائق ناهي ، جيئن اهي چون ٿا. تنهن ڪري، هن اسٽيج تي اسان کي اسان جي ڪم مڪمل ڪندو. آخري ۽ پسنديده شيءِ - اسان هڪ ڪمٽ ٺاهيو، پيغام لکي ٿو: JRTB-3: ٽيليگرام بوٽ ڪمانڊز کي سنڀالڻ لاءِ ڪمانڊ جو نمونو شامل ڪيو ويو آهي ۽ هميشه وانگر - گٿب اڳ ۾ ئي ڄاڻي ٿو ۽ پيش ڪري ٿو پل جي درخواست ٺاهڻ لاءِ: "جاوا پروجيڪٽ A کان Z تائين": بوٽ سان ڪم ڪرڻ لاءِ ڪمانڊ جو نمونو لاڳو ڪرڻ.  حصو 2 - 1تعمير گذري چڪو آهي ۽ توهان اڳ ۾ ئي ڪري سگهو ٿا ملائي... پر نه! مون پروجيڪٽ ورزن کي اپڊيٽ ڪرڻ وسري ويو ۽ ان کي RELEASE_NOTES ۾ لکڻ. اسان نئين ورزن سان هڪ داخلا شامل ڪريون ٿا - 0.2.0-SNAPSHOT: "جاوا پروجيڪٽ A کان Z تائين": بوٽ سان ڪم ڪرڻ لاءِ ڪمانڊ جو نمونو لاڳو ڪرڻ.  حصو 2 - 2اسان هن ورزن کي pom.xml ۾ اپڊيٽ ڪيو ۽ هڪ نئون ڪمٽ ٺاهيو: نئون "جاوا پروجيڪٽ A کان Z تائين": بوٽ سان ڪم ڪرڻ لاءِ ڪمانڊ جو نمونو لاڳو ڪرڻ.  حصو 2 - 3ڪمٽ: JRTB-3: اپڊيٽ ٿيل RELEASE_NOTES.md"جاوا پروجيڪٽ A کان Z تائين": بوٽ سان ڪم ڪرڻ لاءِ ڪمانڊ جو نمونو لاڳو ڪرڻ.  حصو 2 - 4 هاڻي دٻايو ۽ تعمير مڪمل ٿيڻ جو انتظار ڪريو. تعمير گذري چڪو آهي، توهان ان کي ضم ڪري سگهو ٿا: "جاوا پروجيڪٽ A کان Z تائين": بوٽ سان ڪم ڪرڻ لاءِ ڪمانڊ جو نمونو لاڳو ڪرڻ.  حصو 2 - 5مان برانچ کي ختم نه ڪري رهيو آهيان، تنهنڪري توهان هميشه ڏسي سگهو ٿا ۽ موازنہ ڪري سگهو ٿا ڇا تبديلي آئي آهي. اسان جي ٽاسڪ بورڊ کي اپڊيٽ ڪيو ويو آهي:"جاوا پروجيڪٽ A کان Z تائين": بوٽ سان ڪم ڪرڻ لاءِ ڪمانڊ جو نمونو لاڳو ڪرڻ.  حصو 2 - 6

نتيجا

اڄ اسان هڪ وڏو ڪم ڪيو: اسان ڪم لاءِ ڪمانڊ ٽيمپليٽ متعارف ڪرايو. هر شي قائم ڪئي وئي آهي، ۽ هاڻي هڪ نئين ٽيم شامل ڪرڻ هڪ سادي ۽ سڌو عمل هوندو. اسان اڄ به جاچ بابت ڳالهايو. اسان ٽيمن لاءِ مختلف ٽيسٽن ۾ ڪوڊ نه ورجائڻ سان به ٿورو کيڏيو. هميشه وانگر، مان گيٽ هب تي رجسٽر ڪرڻ جي صلاح ڏيان ٿو ۽ هن سيريز ۽ ٻين منصوبن جي پيروي ڪرڻ لاءِ منهنجي اڪائونٽ کي فالو ڪيو جنهن تي آئون اتي ڪم ڪري رهيو آهيان. مون هڪ ٽيليگرام چينل پڻ ٺاهيو جنهن ۾ مان نئين مضمونن جي رليز کي نقل ڪندس. هڪ دلچسپ ڳالهه اها آهي ته ڪوڊ عام طور تي آرٽيڪل کان هڪ هفتو اڳ جاري ڪيو ويندو آهي، ۽ چينل تي آئون هر وقت اهو لکندو آهيان ته ڪو نئون ڪم مڪمل ڪيو ويو آهي، جيڪو مون کي مضمون پڙهڻ کان اڳ ڪوڊ معلوم ڪرڻ جو موقعو ڏيندو. جلد ئي آئون هن بوٽ کي جاري رکڻ جي بنياد تي شايع ڪندس، ۽ جيڪي ٽيليگرام چينل کي سبسڪرائب ڪندا ان جي باري ۾ سڀ کان پهريان ڄاڻندا؛) پڙهڻ لاء توهان سڀني جي مهرباني، جاري رکڻ لاء.

سيريز ۾ سڀني مواد جي هڪ فهرست هن مضمون جي شروعات ۾ آهي.

تبصرا
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION