Need help For building Testing Framework - java

Recently I was trying to build a framework like TestNG but struck at Launcher thing(I don't know whether it is Launcher problem or Something else just guessing). So this is what I did.
First I created a Custom annotation named Test
Wrote a implementation class of test annotation with main method(right now I am targeting only one annotation)
In main method of implementation class i wrote code to read xml(so that i can get the class name and using reflection I am checking the method of the class with Test annotation and invoking it).
Now I wrote another class with method having test annotation and mentioned the class name in the xml file. Now when we use testng we get option of running that method/class as TestNG.
But in my case I don't know how to run my Class because there is no main method.
So I am Struck at this Point. Please suggest what I should do. If we need Launcher then please tell how we create launcher or any tutuorial/Book/weblink which contains information about Launcher.
*Note: I know if we use annotation we don't need XML file. But for Simplifying thing I am getting class name from XML later I will discard XML.
Thanks in Advance .
This is My Test Annoatation
package com.annoatation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
#Target(value=ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface Test {
}
This is my Class Where I am Using Annaotation:
package com.annoatation;
public class TestExample{
#Test
public void sampleMethod()
{
System.out.println("This is sample method");
}
#Test
public void sampleMethod1()
{
System.out.println("This is sample method 1");
}
}
This is my Main Class :
package com.annoatation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Main {
public static void main(String[] args) {
TestExample example=new TestExample();
Method[] method=example.getClass().getMethods();
for(Method methods:method)
{
Test test=methods.getAnnotation(com.annoatation.Test.class);
if(test!=null)
{
try {
methods.invoke(example);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
I want when i Click on Run as on My TestExample Class it should Automatically invoke the main Method of main Class.
I am not sure what we say this thing in java (May be Entry point)

Use reflection to create an instance of your class and invoke the annotated method:
Class classDefinition = Class.forName(className);
object = classDefinition.newInstance();
Method method = classDefinition.getMethod("methodName");
method.invoke(object);

Related

Unable to add a Telegram Bot Library; Beginners fail?

I've just started to go away from tasks of the university and do my own projects.
I want to program a Java Telegram Bot to interact with further classes. Unfortunately I'm not able to add the dependency right or it just cant import all of the functions. I tried to follow multiple tutorials but I got errors in either of them. One of the most promising tutorials was the following: https://github.com/rubenlagus/TelegramBots/wiki/Getting-Started
I followed the instructions (added the library with Maven) and put in the code. After this I imported the needed librarie. However the program isn't able to call the method "execute" and I don't know why.
I hope I specified the topic detailled enough.
Thank you in advance.
Main Class:
import org.telegram.telegrambots.ApiContextInitializer;
import org.telegram.telegrambots.meta.TelegramBotsApi;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.meta.generics.LongPollingBot;
public class Main {
public static void main(String[] args) {
ApiContextInitializer.init();
TelegramBotsApi botsApi = new TelegramBotsApi();
try {
botsApi.registerBot((LongPollingBot) new Bot());
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
}
Bot Class
import org.telegram.telegrambots.api.objects.Update;
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
public class Bot extends TelegramLongPollingBot {
#Override
public void onUpdateReceived(Update update) {
// We check if the update has a message and the message has text
if (update.hasMessage() && update.getMessage().hasText()) {
SendMessage message = new SendMessage() // Create a SendMessage object with mandatory fields
.setChatId(update.getMessage().getChatId())
.setText(update.getMessage().getText());
try {
execute(message); // Call method to send the message
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
}
#Override
public String getBotUsername() {
return null;
}
#Override
public String getBotToken() {
return null;
}
#Override
public void onClosing() {
}
}
Error
Error:(16, 17) java: cannot find symbol
symbol: method execute(org.telegram.telegrambots.meta.api.methods.send.SendMessage)
location: class Bot
in the POM.xml file I added the follow dependency:
<!-- https://mvnrepository.com/artifact/org.telegram/telegrambots -->
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots</artifactId>
<version>4.9.2</version>
</dependency>
You can also download directly the jar.
You must create and define the bot with BotFather, use a username, take the token and create the class that extends TelegramLongPollingBot.
Your problem is on the token and username that return always null. You must return the configuration created with BothFather.
You must set in the getters botToken and botUsername the token and username of bot.
return "<token>";
return "<username_of_bot>";
at least minimum the token.

Byte Buddy Member Substitution throwing IllegalStateException error

I'm trying to write a java instrumentation agent using byte buddy. My goal is to replace a java standard library method call with a proxy call of my own. I was suggested to use Byte Buddy's MemberSubstitution to achieve this. I used this and this questions from SO for my reference.
I'm using Intellij IDEA for coding. My Agent code is split into multiple files as follows:
MyFirstAgent.java
public class MyFirstAgent {
public static void premain(String agentArgs, Instrumentation inst) {
new AgentBuilder.Default()
.type(ElementMatchers.any())
.transform(new ByteBuddyTransformer())
.with(AgentBuilder.Listener.StreamWriting.toSystemOut())
.with(AgentBuilder.TypeStrategy.Default.REDEFINE)
.installOn(inst);
}
ByteBuddyTransformer.java
public class ByteBuddyTransformer implements AgentBuilder.Transformer {
#Override
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription,
ClassLoader classLoader, JavaModule javaModule) {
try {
return builder.visit(MemberSubstitution.relaxed()
.method(named("add"))
.replaceWith(MyClass.class.getMethod("printLine"))
.on(any()));
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
return builder;
}
}
MyClass.java
public class MyClass {
public boolean printLine(){
System.out.println("This is the proxy!");
return true;
}
}
And the application that I want to instrument is in another Intellij IDEA project with the following:
Main.java
public class Main {
public static void main(String[] args) {
ClassToMonitor classToMonitor = new ClassToMonitor();
classToMonitor.bar();
}
}
ClassToMonitor.java
package com.company;
import java.util.ArrayList;
import java.util.Arrays;
public class ClassToMonitor {
public void bar() {
// create an empty array list with an initial capacity
ArrayList<Integer> arrlist = new ArrayList<Integer>(5);
// use add() method to add elements in the list
arrlist.add(15);
// print all the elements available in list
for (Integer number : arrlist) {
System.out.println("Number = " + number);
}
}
}
When I build the fat jar of my agent and run it with my application, I get the following error:
[Byte Buddy] ERROR com.company.ClassToMonitor [jdk.internal.loader.ClassLoaders$AppClassLoader#2626b418, unnamed module #385e9564, loaded=false]
java.lang.IllegalStateException: Cannot invoke public boolean com.company.MyClass.printLine() on [class java.util.ArrayList, E]
I can provide the full error message if required. Also, I'm new to Java and Instrumentation in general so I might be missing something fundamental here, please kindly excuse me and point it out if that's the case.
For substitution to work, the target method needs to accept the same arguments as the replaced method, in your case an int. Also, since you are calling a member, the implicit first argument of your class needs to be the receiver type, i.e. ArrayList or any super type, even Object. Also, your replacement method needs to be static:
public class MyClass {
public static boolean printLine(Object ignored, int ignored2){
System.out.println("This is the proxy!");
return true;
}
}
MemberSubstitution is still not as flexible as it is supposed to be. You can however already inject custom byte code using the chained step if that is what you want.

Pragmatically allow User to pick which JUnit Test Classes will be run

I am trying to pass a list of classes as a parameter. (Can I do this?) I am using JUnit and Selenium, I have JUnit test classes that are called by a JUnit test suite class, using #SuiteClasses() and that test suite class is called by a class containing a main(). My idea is to allow the user to pick JUnit classes from the main class which will be stored in some kind of list. The Test Suite that calls the JUnit test classes to be run will use that list and call those JUnit classes.
Original Code: the test suite class that calls the JUnit test classes that should be run (works) ⬇
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
#RunWith(Suite.class)
#SuiteClasses({ TestCase1.class, TestCase2.class})
public class AllTests {
}
I am trying to change it to something like ⬇
#SuiteClasses(runnerClass.classesToTest)
and in the runner class I would have something like this. I was thinking, I can pull names of classes from prop file maybe, and allow the user to pick which classes will be added to variable classesToTest ⬇
public class runnerClass {
public static Class<?>[] classesToTest = { testCase1.class, testCase2.class };
public static void main(String[] args) {
...
}
}
When I try to do something like this, I get this error ⬇
The value for annotation attribute Suite.SuiteClasses.value must be a class literal
JavaDoc for #SuiteClasses()
So question being, can I make this work? Am I creating my classesToTest variable incorrectly?
I could not find any solution in the JUnit framework, so I wrote a quick and dirty Test runner. It just calls all Methods annotated with #Test, even non-accessible ones (just in case).
It won't work with any IDE included UnitTest result displaying tools.
It is used like the following:
public static void main(String[] args) {
Runner run = new Runner(TestCase.class, TestCase2.class);
for(Exception e : run.runUnchecked()) {
System.err.println(e.getCause());
}
}
You can pass the Classes either as vararg or a normal array, both will work. The Runner will return a List of Exceptions of the tests. If a test fails, it throws an Exception, either the exception that caused the fail, or if an assertion failed, then a AssertionFailedError is thrown. You can easily print a one line description with e.getCause(), this will display a message like this: org.opentest4j.AssertionFailedError: expected: <1> but was: <2>
My example Code works with JUnit Jupiter tests, you can adapt it by changing which Test class is imported in the Runner class. This has to be the same, that is used for your TestCases.
Here is the Code
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.Test;
/**
* A simple JUnit Test Case Runner, which can dynamically call TestCases by
* their class.
*
* #author Alexander Daum
*
*/
public class Runner {
private Class<?>[] testCases;
public Runner(Class<?>... testCases) {
this.testCases = testCases;
}
/**
* Run all TestCases given in the constructor of this Runner.
*
* #throws InvocationTargetException
* #throws IllegalArgumentException
* #throws IllegalAccessException
* #throws InstantiationException
*/
public List<Exception> run()
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
List<Exception> testErrors = new ArrayList<>();
for (Class<?> testClazz : testCases) {
Object testCase = testClazz.newInstance();
Method[] methods = testClazz.getDeclaredMethods();
methods = Arrays.stream(methods).filter(m -> m.isAnnotationPresent(Test.class)).toArray(Method[]::new);
for (Method m : methods) {
m.setAccessible(true);
try {
m.invoke(testCase);
} catch (InvocationTargetException e) {
testErrors.add(e);
}
}
}
return testErrors;
}
/**
* The same as {#link Runner#run()}, but all exceptions are wrapped in
* RuntimeException, so no try catch is neccessary, when Errorhandling is not
* required
*/
public List<Exception> runUnchecked() {
try {
return run();
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
| InstantiationException e) {
throw new RuntimeException(e);
}
}
}

Testing ClassNotFound Exception

I'm trying to test that a class is not found with UnitTest on Android.
What's going on:
1. I'm writing an android library with transitive dependencies which are resolved in the host application
2. The developer may remove some dependencies for example remove all com.example.package
3. I have a Factory that will try to instantiate (using reflection) an Object and catch the ClassNotFoundException. If the developer remove the dependencies, the exception should be thrown.
4. I want to test this case, but all I found is issue with dependencies, not how to test for it.
Example code I want to test
try {
sNetworkResponseBuilderClass = OkHttpNetworkResponse.Builder.class;
} catch (Exception e){
// <<<< I want to test this case
new ClassNotFoundException("Unable to find OkHttpNetworkResponse.Builder.class").printStackTrace();
return null;
}
library used: hamcrast, mockito, JUnit 4.
Do you know how to do it?
So for me the first thing you need to do is to extract the part of the code that can throw a ClassNotFoundException in order to be able to easily mock it, something like:
public Class<? extends NetworkResponseBuilder> getNetworkResponseBuilderClass()
throws ClassNotFoundException {
// Your logic here
}
Then you can test a real factory instance using Mockito.spy to be able to redefine the behavior of the method getNetworkResponseBuilderClass() as next:
public void testFactoryIfNetworkResponseBuilderNotFound() {
Factory factory = spy(new Factory());
when(factory.getNetworkResponseBuilderClass()).thenThrow(
new ClassNotFoundException()
);
// The rest of your test here
}
public void testFactoryIfNetworkResponseBuilderFound() {
Factory factory = spy(new Factory());
when(factory.getNetworkResponseBuilderClass()).thenReturn(
OkHttpNetworkResponse.Builder.class
);
// The rest of your test here
}
More details about Mockito.spy.
Not quite sure if I understood your question correctly, but you can check with JUnit if an exception gets thrown:
#Test(expected=ClassNotFoundException.class)
public void testClassNotFoundException() {
// a case where the exception gets thrown
}
OkHttpNetworkResponse.Builder might be as follows:
package com.example.model;
public class OkHttpNetworkResponse {
public static class Builder {
}
}
I have a Factory that will try to instantiate (using reflection) an Object and catch the ClassNotFoundException. If the developer remove
the dependencies, the exception should be thrown.
Factory Class: which will create any object might be as follows:
package com.example.factory;
public class Factory {
public static Object getInstance(String className)
throws ClassNotFoundException, InstantiationException,
IllegalAccessException {
Class clazz = Class.forName(className);
return clazz.newInstance();
}
}
The developer may remove some dependencies for example remove all com.example.package
I want to test this case, but all I found is issue with dependencies, not how to test for it.
FactoryTest Class: which will test whether ClassNotFoundException is thrown or not might be as follows: N.B: please Check the comments carefully.
package com.example.factory;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import org.junit.Test;
public class FactoryTest {
Factory factory;
#Test(expected=ClassNotFoundException.class)
public void test() throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
ClassLoader loader = FactoryTest.class.getClassLoader();
String directory = loader.getResource(".").getPath() + "/com/example/model";
File dir = new File(directory);
//Checking directory already existed or not..
assertTrue("Directory:"+dir.getPath()+" not exist",dir.exists());
//Deleting directory
deleteDirectoryProgramatically(directory);
//Checking directory already deleted or not..
assertFalse("Directory:"+dir.getPath()+" still exist",dir.exists());
//Now getInstance Method will throw ClassNotFoundException because OkHttpNetworkResponse.Builder.class has been deleted programatically.
Factory.getInstance("OkHttpNetworkResponse.Builder.class");
}
private void deleteDirectoryProgramatically(String directory) {
File dir = new File(directory);
System.out.println(dir.getAbsolutePath());
String[] files = dir.list();
for (String f : files) {
File fl = new File(directory,f);
System.out.println(f+ " deleted?"+fl.delete());
}
System.out.println(dir+ " deleted?"+dir.delete());
}
}
It is very simple issue. JUnit4 exception unit testing is given below with an example. Hope it will clarify you.
MyNumber.java
public class MyNumber {
int number;
public MyNumber div(MyNumber rhs) {
if (rhs.number == 0) throw new IllegalArgumentException("Cannot divide by 0!");
this.number /= rhs.number;
return this;
}
}
MyNumberTest.java
public class MyNumberTest {
private MyNumber number1, number2; // Test fixtures
#Test(expected = IllegalArgumentException.class)
public void testDivByZero() {
System.out.println("Run #Test testDivByZero"); // for illustration
number2.setNumber(0);
number1.div(number2);
}
}
JUnit - Exceptions Test
To test if the code throws a desired exception, use annotation #Test(expected = exception.class), as illustrated in the previous example. For your case it will be
/**
* Check for class not found exception
**/
#Test(expected=ClassNotFoundException.class)
public void testClassNotFoundException() {
.....
}
For better understanding, you can go through this tutorial: Java Unit
Testing - JUnit & TestNG. It contains full running code example
step by step with explanation.
inside catch you can check the object with the instanceof operator as :
try {
sNetworkResponseBuilderClass = OkHttpNetworkResponse.Builder.class;
} catch (Exception e){
if(e instanceof ClassNotFoundException){
// here you can do the code you want in case of ClassNotFoundException thrown
}
}
it is your dictionary problem. in your dictionary in test class will not have . change your dictionary.
Use Class.forName("com.example.ClassName")
try {
Class.forName("com.example.OkHttpNetworkResponse.Builder");
} catch (ClassNotFoundException e) {
// This class was not found
}
See Class.forName(String className)

gwtent reflection java

Welcome,
I have a problem with "GWTENT" reflection.
How to create a class using reflection?
I tried this:
try {
ClassType ct = TypeOracle.Instance.getClassType(Klient.class);
ct.invoke(null, "Klient", null);
} catch (ReflectionRequiredException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
`
call the class:
package pl.cba.lukaszbaczek.client.Test;
import com.extjs.gxt.ui.client.widget.Window;
import com.google.gwt.user.client.Element;
import com.gwtent.reflection.client.Reflectable;
import com.gwtent.reflection.client.Reflection;
#Reflectable
public class Klient extends Window implements Reflection {
#Override
protected void onRender(Element parent, int index) {
super.onRender(parent, index);
setHeading("Klient");
setSize(600, 600);
}
public Klient(){
super();
show();
}
}
But fails with the error:
17:30:59.129 [ERROR] [makerbase] Uncaught exception escaped
com.gwtent.reflection.client.NotFoundException: Klient not found or unimplement?
If you are on the client side which is compiled into javascript you cannot use reflection. You can use GWT.create(Clazz.class) but the class signature must be known at compile time. This is a requirement due to the javascript compiler.
Here is a link that uses generators for doing reflection
Can you use Java Reflection api in GWT client

Categories