اسان اپليڪيشن لاء ٽيسٽ لکندا آهيون
مضمون جي شروعات:
لکڻ 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 {
String chatId = "test_chat_id";
String message = "test_message";
SendMessage sendMessage = new SendMessage();
sendMessage.setText(message);
sendMessage.setChatId(chatId);
sendMessage.enableHtml(true);
sendBotMessageService.sendMessage(chatId, message);
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() {
Arrays.stream(CommandName.values())
.forEach(commandName -> {
Command command = commandContainer.retrieveCommand(commandName.getCommandName());
Assertions.assertNotEquals(UnknownCommand.class, command.getClass());
});
}
@Test
public void shouldReturnUnknownCommand() {
String unknownCommand = "/fgjhdfgdfg";
Command command = commandContainer.retrieveCommand(unknownCommand);
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 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 {
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);
getCommand().execute(update);
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: ٽيليگرام بوٽ ڪمانڊز کي سنڀالڻ لاءِ ڪمانڊ جو نمونو شامل ڪيو ويو آهي ۽ هميشه وانگر - گٿب اڳ ۾ ئي ڄاڻي ٿو ۽ پيش ڪري ٿو پل جي درخواست ٺاهڻ لاءِ:
تعمير گذري چڪو آهي ۽ توهان اڳ ۾ ئي ڪري سگهو ٿا ملائي... پر نه! مون پروجيڪٽ ورزن کي اپڊيٽ ڪرڻ وسري ويو ۽ ان کي RELEASE_NOTES ۾ لکڻ. اسان نئين ورزن سان هڪ داخلا شامل ڪريون ٿا - 0.2.0-SNAPSHOT:
اسان هن ورزن کي pom.xml ۾ اپڊيٽ ڪيو ۽ هڪ نئون ڪمٽ ٺاهيو: نئون
ڪمٽ:
JRTB-3: اپڊيٽ ٿيل RELEASE_NOTES.md هاڻي دٻايو ۽ تعمير مڪمل ٿيڻ جو انتظار ڪريو. تعمير گذري چڪو آهي، توهان ان کي ضم ڪري سگهو ٿا:
مان برانچ کي ختم نه ڪري رهيو آهيان، تنهنڪري توهان هميشه ڏسي سگهو ٿا ۽ موازنہ ڪري سگهو ٿا ڇا تبديلي آئي آهي. اسان جي ٽاسڪ بورڊ کي اپڊيٽ ڪيو ويو آهي:
نتيجا
اڄ اسان هڪ وڏو ڪم ڪيو: اسان ڪم لاءِ ڪمانڊ ٽيمپليٽ متعارف ڪرايو. هر شي قائم ڪئي وئي آهي، ۽ هاڻي هڪ نئين ٽيم شامل ڪرڻ هڪ سادي ۽ سڌو عمل هوندو. اسان اڄ به جاچ بابت ڳالهايو. اسان ٽيمن لاءِ مختلف ٽيسٽن ۾ ڪوڊ نه ورجائڻ سان به ٿورو کيڏيو.
هميشه وانگر، مان گيٽ هب تي رجسٽر ڪرڻ جي صلاح ڏيان ٿو ۽ هن سيريز ۽ ٻين منصوبن جي پيروي ڪرڻ لاءِ منهنجي اڪائونٽ کي فالو ڪيو جنهن تي آئون اتي ڪم ڪري رهيو آهيان. مون هڪ ٽيليگرام چينل پڻ ٺاهيو جنهن ۾ مان نئين مضمونن جي رليز کي نقل ڪندس. هڪ دلچسپ ڳالهه اها آهي ته ڪوڊ عام طور تي آرٽيڪل کان هڪ هفتو اڳ جاري ڪيو ويندو آهي، ۽ چينل تي آئون هر وقت اهو لکندو آهيان ته ڪو نئون ڪم مڪمل ڪيو ويو آهي، جيڪو مون کي مضمون پڙهڻ کان اڳ ڪوڊ معلوم ڪرڻ جو موقعو ڏيندو. جلد ئي آئون هن بوٽ کي جاري رکڻ جي بنياد تي شايع ڪندس، ۽ جيڪي ٽيليگرام چينل کي سبسڪرائب ڪندا ان جي باري ۾ سڀ کان پهريان ڄاڻندا؛) پڙهڻ لاء توهان سڀني جي مهرباني، جاري رکڻ لاء.
GO TO FULL VERSION