What i do wrong?
It says me: The constructor DefaultShardManagerBuilder() is deprecated.
But Why and how can i Fix it (its my first code)
public class DonaldBot {
public ShardManager shardMan;
public static void main(String[] args) {
try {
new DonaldBot();
} catch (LoginException | IllegalArgumentException e) {
e.printStackTrace();
}
}
public DonaldBot() throws LoginException, IllegalArgumentException {
DefaultShardManagerBuilder builder = new DefaultShardManagerBuilder();
builder.setToken("NzUzNjI0NzU0MDI3NjI2NTg2.X1o5vw.1oT_Hhn6FVaZf8ewIHOkrTcEU-M");
builder.setActivity(Activity.watching("Chil Ecke"));
builder.setStatus(OnlineStatus.ONLINE);
builder.addEventListeners(new CommandListener());
this.shardMan = builder.build();
System.out.println("[Donald] Bot Online.");
According to the documentation, "Due to breaking changes to the discord api gateway you are now required to explicitly state which events your bot needs.". This answers the "why" part of your question.
Regarding the "how can I fix it", I'd try DefaultShardManagerBuilder builder = DefaultShardManagerBuilder.create(...).
Related
I have a class which I have annotated as #injectMock. This class has a constructor which loads messages from in put stream as below:
public class RegistrationEventValidator {
private Properties validationMessages;
RegistrationEventValidator() {
validationMessages = new Properties();
try {
validationMessages.load(RegistrationEventValidator.class.getClassLoader().getResourceAsStream("ValidationMessages.properties"));
} catch (IOException e) {
throw new InternalErrorException("Failed loading ValidationMessages.properties");
}
}
}
My test covers up until the "catch exception". How do I unit test that part? Thank you.
This is what I have so far and I am getting this error: "org.opentest4j.AssertionFailedError: Expected com.autonation.ca.exception.InternalErrorException to be thrown, but nothing was thrown"
#Test
void test_validation_messages_properties() throws IOException {
//given
List<String> errors = new ArrayList<>();
Event<AuthEventDetails> event = new Event<>();
AuthEventDetails request = new AuthEventDetails();
event.setCustomerId(RandomStringUtils.random(65));
request.setFirstName(RandomStringUtils.random(256));
request.setLastName(RandomStringUtils.random(256));
event.setEventDetails(request);
doThrow(new InternalErrorException("Failed loading ValidationMessages.properties")).when(validationMessages).load(any(InputStream.class));
assertThrows(InternalErrorException.class, () -> registrationEventValidator.validate(event, errors));
}
Please help me how am I going to cover the privated method in my class used in a public method. Whenever I run my JUnit coverage, it says that that private method has a missing branch.
Here is the code that uses that private method:
public String addRecord(Record rec) throws IOException {
GeoPoint geoPoint = locationService.getLocation(rec.getTerminalId());
if (Objects.isNull(geoPoint)) {
loggingService.log(this.getClass().toString(), rec.getTerminalId(), "GET LOCATION",
"No Coordinates found for terminal ID: " + rec.getTerminalId());
return "No Coordinates found for terminal ID: " + rec.getTerminalId();
}
loggingService.log(this.getClass().toString(), rec.getTerminalId(), "GeoPoint",
"Latitude: " + geoPoint.getLat() + " Longitude: " + geoPoint.getLon());
format(rec);
loggingService.log(this.getClass().toString(), rec.getTerminalId(), "addRecord",
"Formatted Payload" + rec.toString());
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject().field("terminalId", rec.getTerminalId())
.field("status", "D".equals(rec.getStatus()) ? 1 : 0).field("recLocation", rec.getLocation())
.field("errorDescription", rec.getErrorDescription()).field("lastTranTime", rec.getLastTranTime())
.field("lastDevStatTime", rec.getLastDevStatTime()).field("errorCode", rec.getErrorCode())
.field("termBrcode", rec.getTermBrcode()).timeField("#timestamp", new Date())
.latlon("location", geoPoint.getLat(), geoPoint.getLon()).endObject();
IndexRequest indexRequest = new IndexRequest(prop.getEsIndex(), prop.getEsType(), rec.getTerminalId())
.source(builder);
IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);
loggingService.log(this.getClass().toString(), rec.getTerminalId(), TraceLog.SUCCESSFUL_PUSH_TO_ELASTIC_SEARCH,
util.mapToJsonString(rec));
return response.getResult().name();
}
This is the the private method:
private Record format(Record rec) {
if (rec.getLocation() == null) {
rec.setLocation("");
}
if (rec.getTermBrcode() == null) {
rec.setTermBrcode("");
}
if (rec.getErrorDescription() == null) {
rec.setErrorDescription("");
}
return rec;
}
This is my Junit code:
#Before
public void setUp() throws ParseException, IOException {
client = mock(RestHighLevelClient.class);
indexRequest = mock(IndexRequest.class);
indexResponse = mock(IndexResponse.class);
MockitoAnnotations.initMocks(this);
rec= new Record();
rec.setLocation("location");
rec.setStatus("U");
rec.setErrorCode("222");
rec.setErrorDescription("STATUS");
rec.setLastDevStatTime("02-02-2020");
rec.setLastTranTime("02-02-2020");
rec.setTerminalId("123");
rec.setTermBrcode("111");
ReflectionTestUtils.setField(client, "client", restClient);
}
#Test
public void testAddRecordIsNull()
throws IOException, NumberFormatException, IllegalArgumentException, IllegalAccessException {
Mockito.when(locationService.getLocation(Mockito.anyString())).thenReturn(null);
elasticsearchService.addRecord(rec);
assertThat(1).isEqualTo(1);
}
#Test
public void testFormat() throws IOException {
rec = new Record();
rec.setLocation(null);
rec.setStatus(null);
rec.setErrorCode(null);
rec.setErrorDescription(null);
rec.setLastDevStatTime(null);
rec.setLastTranTime(null);
rec.setTerminalId(null);
rec.setTermBrcode(null);
elasticsearchService.addRecord(rec);
//ReflectionTestUtils.invokeMethod(ElasticsearchService.class, "addAtmStatusRecord", rec);
Mockito.when(elasticsearchService.addRecord(null)).thenReturn("");
//elasticsearchService.addRecord(atm);
//Mockito.when(locationService.getLocation(Mockito.anyString())).thenReturn(atm);
//elasticsearchService.addRecord(null);
assertThat(1).isEqualTo(1);
}
Please help me on where am I missing on my JUnit to cover the private method 'format'. Any help will be much appreciated. Thanks.
In testFormat, if elasticsearchService.addRecord is being tested, it shouldn't mocked. i.e. Remove Mockito.when(elasticsearchService.addRecord(null)).thenReturn("");
What should be mocked are the services / dependencies used in the method. e.g. loggingService
xxx
Update #1: EclEmma is telling you that the body of the if statements are red. This means that testAddRecordIsNull is not configured correctly. It is passing a Record object that has values. Instead of passing rec, pass new Record(). This assumes that the attributes of the new Record has default values of null. If you need to have a Record that has values for other attributes, create a new record accordingly.
Yes! I finally found the solution.
#Test
public void testFormat() throws IOException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
rec= new Record();
rec.setLocation(null);
rec.setStatus(null);
rec.setErrorCode(null);
rec.setErrorDescription(null);
rec.setLastDevStatTime(null);
rec.setLastTranTime(null);
rec.setTerminalId(null);
rec.setTermBrcode(null);
java.lang.reflect.Method method = ElasticsearchService.class.getDeclaredMethod("format", Record.class);
method.setAccessible(true);
Record output = (Record) method.invoke(es, rec);
assertEquals(output, rec);
}
Reflection is the key. Sharing it here so others running on the same issue might have this for assistance. Thanks.
I'm currently working on my discord bot. One problem I encountered is that I'm not able to find out how to allow the bot to wait for a user reply after a message is sent.
I also have tried reading the git documentation regarding using RestAction over here: https://github.com/DV8FromTheWorld/JDA/wiki/7)-Using-RestAction but it seems it does not mention anything about implementing an "await" function similar to discord.js
I tried coding to mimic such an effect:
public class EventHandler extends ListenerAdapter {
private static final String PREFIX = "&";
public static String[] args;
public void sendMessage(String s, GuildMessageReceivedEvent event) {
event
.getChannel()
.sendMessage(s)
.queue();
}
public void onGuildMessageReceived (GuildMessageReceivedEvent event) {
args = event
.getMessage()
.getContentRaw()
.split(" ");
if (args[0].equalsIgnoreCase(PREFIX + "any_command")) {
sendMessage("Type hello!");
if (args[0].equalsIgnoreCase(PREFIX + "hello") {
sendMessage("hello there!");
}
}
}
}
Main class:
import net.dv8tion.jda.core.AccountType;
import net.dv8tion.jda.core.JDA;
import net.dv8tion.jda.core.JDABuilder;
public class Main {
public static void main(String[] args) throws Exception {
JDA jda = new JDABuilder(AccountType.BOT)
.setToken("token goes here")
.setAutoReconnect(true).build();
try {
jda.addEventListener(new EventHandler());
} catch (Exception e) {
e.printStackTrace();
}
}
}
This doesn't register the hello command typed after the prompt given. My best guess would be that the condition is never met since the original condition overrides the upcoming one (args[0] is already any_command)
Any help would be appreciated!
I'd suggest the EventWaiter from JDA-Utilities (https://github.com/JDA-Applications/JDA-Utilities/)
Taking a quick look at the source, looks like you'll need something like this
EventWaiter waiter = new EventWaiter();
// SO wouldn't let me insert new lines for some reason.
waiter.waitForEvent(GuildMessageReceivedEvent.class, (event) -> event.getMessage().getContentRaw().equalsIgnoreCase("hello"), (event) -> event.getChannel().sendMessage("hello!").queue()));
I have following cli wrapper:
public class CLIUtil
{
// some private variable and other methods
public CLIUtil(final String[] args, final Options commandLineOptions) throws ParseException
{
Validate.notEmpty(args);
Validate.notNull(commandLineOptions);
this.commandLineOptions = commandLineOptions;
this.command = this.parser.parse(this.commandLineOptions, args);
}
public void printHelp(final String executableName)
{
Validate.notEmpty(executableName);
final HelpFormatter formatter = new HelpFormatter();
formatter.printHelp(executableName, this.commandLineOptions);
}
}
Which have following problems:
As we are throwing exception in constructor:
if args as null. There is no way to printHelp.
if args are invalid. There is no way to printHelp.
I am thinking of following solution:
Solution 1:
public CLIUtil(final String executableName, final Options commandLineOptions) throws ParseException
{
Validate.notNull(commandLineOptions);
this.commandLineOptions = commandLineOptions;
this.executableName = executableName;
}
public void parseArgs(final String[] args) throws ParseException
{
Validate.notEmpty(args);
this.command = this.parser.parse(this.commandLineOptions, args);
}
Problem with this solution is:
User need to call set after constructor. so we are letting client to control the flow.
Solution 2:
public CLIUtil(final String executableName, String[] args, final Options commandLineOptions) throws ParseException
{
if (null == args) {
// show help and throw illegal arg
}
Validate.notNull(commandLineOptions);
this.commandLineOptions = commandLineOptions;
this.executableName = executableName;
try {
this.command = this.parser.parse(this.commandLineOptions, args);
} catch (Parse...) {
// catch exception and show error and printhelp followed by
// throw same exception
}
}
Problem with this solution is:
1) Random placement of validation rule.
Do you have a suggestion which solution is better or suggested improvement?
I have the following class:
public class FileLoader {
private Map<Brand, String> termsOfUseText = new HashMap<Brand, String>();
public void load() {
for (Brand brand : Brand.values()) {
readAndStoreTermsOfUseForBrand(brand);
}
}
private void readAndStoreTermsOfUseForBrand(Brand brand) {
String resourceName = "termsOfUse/" + brand.name().toLowerCase() + ".txt";
InputStream in = this.getClass().getClassLoader().getResourceAsStream(resourceName);
try {
String content = IOUtils.toString(in);
termsOfUseText.put(brand, content);
} catch (IOException e) {
throw new IllegalStateException(String.format("Failed to find terms of use source file %s", resourceName),e);
}
}
public String getTextForBrand(Brand brand) {
return termsOfUseText.get(brand);
}
}
Brand is an enum, and I need all the valid .txt files to be on the classpath. How do I make the IOException occur, given that the Brand enum contains all the valid brands and therfore all the .txt files for them exist?
Suggestions around refactoring the current code are welcome if it makes it more testable!
Three options I see right off:
Use PowerMock to mock IOUtils.toString(). I consider PowerMock to be quite a last resort. I'd rather refactor the source to something a little more test-friendly.
Extract the IOUtils call to a protected method. Create a test-specific subclass of your class that overrides this method and throws the IOException.
Extract the InputStream creation to a protected method. Create a test-specific subclass to override the method and return a mock InputStream.
I would suggest a bit of refactoring. All your methods are void, this usually means they are not functional.
For example, you can extract this functionality:
private String readTermsOfUseForBrand(InputStream termsOfUserIs) {
try {
String content = IOUtils.toString(in);
return content;
} catch (IOException e) {
throw new IllegalStateException(String.format("Failed to find terms of use source file %s", resourceName), e);
}
return null;
}
So that we can assert on the String result in our tests.
Of course this is not functional code, as it reads from an Input Stream. And it does so with IOUtils.toString() method that cannot be mocked easily (well, there's PowerMock but as Ryan Stewart said it's the last resort).
To test IO exceptions you can create a failing input stream (tested with JDK7):
public class FailingInputStream extends InputStream {
#Override
public int read() throws IOException {
throw new IOException("Test generated exception");
}
}
And test like that:
#Test
public void testReadTermsOfUseForBrand() {
FileLoader instance = new FileLoader();
String result = instance.readTermsOfUseForBrand(new FailingInputStream());
assertNull(result);
}
Missing file will cause NullPointerException because getResourceAsStream will return null and you will have in==null. IOException in this case may actually be pretty rare. If it's critical for you to see it, I can only think of instrumenting this code to throw it if code is executed in test scope. But is it really that important?
I would use a mock to accomplish this.
Example (untested, just to give you some thought):
#Test(expected=IllegalStateException.class)
public void testThrowIOException() {
PowerMockito.mockStatic(IOUtils.class);
PowerMockito.when(IOUtils.toString()).thenThrow(
new IOException("fake IOException"));
FileLoader fileLoader = new FileLoader();
Whitebox.invokeMethod(fileLoader,
"readAndStoreTermsOfUseForBrand", new Brand(...));
// If IllegalStateException is not thrown then this test case fails (see "expected" above)
}
Code below is completely untested
To cause the IOException use:
FileInputStream in = this.getClass().getClassLoader().getResourceAsStream(resourceName);
in.mark(0);
//read some data
in.reset(); //IOException
To test the IOException case use:
void test
{
boolean success = false;
try
{
//code to force ioException
}
catch(IOException ioex)
{
success = true;
}
assertTrue(success);
}
In JUnit4
#Test(expected=IOException.class)
void test
{
//code to force ioException
}
Other JUnit
void test
{
try
{
//code to force IOException
fail("If this gets hit IO did not occur, fail test");
}
catch(IOException ioex)
{
//success!
}
}