Programma üçin synaglar ýazýarys
Makalanyň başy:
JRTB-3 ýazmak . Indi synag hakda pikirlenmeli. Addedhli goşulan kodlar, işleýşimiziň garaşyşymyz ýaly işleýändigine göz ýetirmek üçin synaglar bilen örtülmelidir. Ilki bilen SendBotMessageService hyzmaty üçin birlik synaglaryny ýazarys.
Bölüm synagy, programmanyň käbir ownuk böleginiň logikasyny barlaýan synag: köplenç bu usullar. Bu usuly bolan ähli baglanyşyklar, masgaralary ulanyp ýasama baglanyşyklar bilen çalşyrylýar. |
Indi hemme zady görersiň. Şol bir paketde, diňe
./src/test/java bukjasynda , synap görjek synpymyz bilen birmeňzeş at döredýäris we ahyrynda
Test goşarys . Sendagny,
SendBotMessageService üçin SendBotMessageServiceTest bolar , bu synp üçin ähli synaglary öz içine alar. Synagdaky pikir şeýleräk: ýasama (ýasama) JavaRushTelegarmBot-a süýşýäris, soň ýerine ýetiriş usulynyň şeýle argument bilen çagyrylandygyny ýa-da ýokdugyny soraýarys. Ine, näme boldy:
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-dan peýdalanyp, hyzmatymyzyň konstruktoryna gowşurylan JavaRushBot obýektini döretdim. Soň bolsa, bir synag ýazdym (Test düşündirişli her usul aýratyn synag). Bu usulyň gurluşy elmydama birmeňzeş - hiç hili argument talap etmeýär we boş gaýdyp gelýär. Synag ady, synag edýän zatlarymyzy aýtmalydyr. Biziň ýagdaýymyzda, bu: habary dogry ibermeli - habary dogry ibermeli. Synagymyz üç bölege bölünýär:
- blok // berilýär - synag üçin zerur zatlary taýýarlaýan ýerimizde;
- blokirleme // haçan - synag etmegi meýilleşdirýän usulymyzy nirede başlaýarys;
- // soň blokirläň - usulyň dogry işleýändigini ýa-da ýokdugyny barlaýarys.
Hyzmatymyzdaky logika şu wagta çenli ýönekeý bolansoň, bu synp üçin bir synag ýeterlik bolar. Indi CommandContainer üçin synag ýazalyň:
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());
}
}
Bu gaty bir synag däl. Konteýneriň logikasyna daýanýar. Botyň goldaýan ähli buýruklary CommandName sanawynda we konteýnerde bolmaly. Şeýdip, CommandName üýtgeýjileriniň hemmesini aldym, Stream API-e gitdim we hersi üçin konteýnerden buýruk gözledim. Şeýle buýruk bolmadyk bolsa, UnknownCommand yzyna gaýtarylardy. Bu setirde barlaýan zatlarymyz:
Assertions.assertNotEquals(UnknownCommand.class, command.getClass());
“UnknownCommand” -yň deslapky boljakdygyny barlamak üçin aýratyn synag gerek - “
ReturnUnknownCommand” . Bu synaglary täzeden ýazmagyňyzy we derňemegiňizi maslahat berýärin. Toparlar üçin häzirlikçe ýarym resmi synaglar bolar, ýöne ýazylmaly. Logika SendBotMessageService synagy bilen deň bolar, şonuň üçin umumy synag logikasyny AbstractCommandTest synpyna geçirerin we her bir synag synagy miras galar we zerur meýdanlary kesgitlär. Synaglaryň hemmesi birmeňzeş bolansoň, her gezek şol bir zady ýazmak aňsat däl, üstesine-de bu gowy koduň alamaty däl. Umumylaşdyrylan abstrakt synp şeýle boldy:
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);
}
}
Görşüňiz ýaly, her buýrugyň şu ýerde ýazylan synagy işletmeli we dogry ýerine ýetirmelidigini kesgitlänimizden soň, üç sany abstrakt usul bar. Esasy logika abstrakt synpda bolanda şeýle amatly çemeleşme, ýöne jikme-jiklikler nesillerde kesgitlenýär. Aslynda, bu ýerde anyk synaglaryň ýerine ýetirilişi bar:
KömekCommandTest:
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);
}
}
NäbelliCommandTest:
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);
}
}
Oýunyň şemiň gymmatdygy düşnüklidir we AbstractCommandTest-iň kömegi bilen ýazmak aňsat we düşünmek aňsat bolan ýönekeý we düşnükli synaglar bilen gutardyk. Mundan başga-da, gereksiz kodlary köpeltmekden halas bolduk (DRY-a salam -> Özüňizi gaýtalamaň). Mundan başga-da, indi programmanyň ýerine ýetirilişine baha berip biljek hakyky synaglarymyz bar. Botyň özi üçin synag ýazsaňam gowy bolardy, ýöne hemme zat aňsat we umuman netije bermez, belki, oýun olaryň aýdyşy ýaly şemiň gymmaty bolmaz. Şonuň üçin bu etapda biz öz işimizi tamamlarys. Iň soňky we iň halanýan zat - bir borçnama döredýäris, habar ýazýar:
JRTB-3: Telegram Bot buýruklaryny dolandyrmak üçin buýruk nusgasy goşuldy we adat bolşy ýaly - Github çekmek haýyşyny döretmegi eýýäm bilýär we teklip edýär:
Gurluşyk geçdi we siz eýýäm edip bilersiňiz birleşdir ... Nook! Taslama wersiýasyny täzeläp, RELEASE_NOTES-de ýazmagy ýatdan çykardym. Täze wersiýa bilen ýazgy goşýarys - 0.2.0-SNAPSHOT:
Bu wersiýany pom.xml-de täzeleýäris we täze borçnama döredýäris:
Täze borçnama:
JRTB-3: täzelenen RELEASE_NOTES.md Indi gurluşyň tamamlanmagyna basyň we garaşyň. Gurluşyk geçdi, birleşdirip bilersiňiz:
Men şahany pozamok, şonuň üçin hemişe üýtgän zady görüp we deňeşdirip bilersiňiz. Iş toparymyz täzelendi:
Netijeler
Bu gün uly bir iş etdik: iş üçin buýruk şablonyny hödürledik. Hemme zat düzüldi, indi täze topar goşmak ýönekeý we gönümel iş bolar. Synag barada hem şu gün gürleşdik. Hatda toparlar üçin dürli synaglarda kody gaýtalamazlyk bilen azajyk oýnadyk.
Hemişe bolşy ýaly, GitHub-da hasaba durmagy we bu seriýany we şol ýerde işleýän beýleki taslamalarymy yzarlamak üçin hasabymy yzarlamagy maslahat berýärin . Şeýle hem , täze makalalaryň çykmagyny köpeltjek telegram kanalyny döretdim . Bir gyzykly zat, kod adatça makalanyň özünden bir hepde öň çykýar we kanala her gezek täze bir iş gutarandan soň ýazaryn, bu makalany okamazdan ozal kody anyklamaga mümkinçilik berer. Soonakyn wagtda boty yzygiderli esasda çap ederin we telegram kanalyna ýazylanlar bu barada ilkinji bolup bilerler;) Okanyňyz üçin sag boluň, dowamy.
GO TO FULL VERSION