I'm fairly new to java and I'm trying to test some of my methods in a class but I got the NullPointerException
public class ArrayListTest {
private List ar;
#org.junit.Before
public void setUp() throws Exception {
List ar = new ArrayList();
}
#Test
public void testAdd() throws Exception {
System.out.println(ar);
***ar.add(33);***
The error points at ar.add(33);
java.lang.NullPointerException
at com.company.ArrayListTest.testAdd(ArrayListTest.java:23)
...a bunch of other invokes...
Looking into add method, I can't find anything wrong.
public class ArrayList implements List{
private Object[] elems;
private int nrElems;
public ArrayList() {
nrElems = 0;
elems = new Object[10];
}
public void add(Object e) {
System.out.println(e);
if (nrElems == elems.length) {
resize();
}
elems[nrElems++] = e;
}
Any ideas? The test class is using my own implementation of ArrayList
Related
I'm testing with Java reflection and trying to apply overloaded method to parameters according to their type..
However, I have NoSuchMethodException even though the method I tried to get is public. This exception still appears when I used getDeclaredMethod.
Here's the main program
public class Test {
public static void main(Object... inputs){
InputManipulation test = new InputManipulation();
for (Object input: inputs){
Class ownerClass = test.getClass();
Class inputClass = input.getClass();
Method method = ownerClass.getDeclaredMethod("add", inputClass);
method.invoke(test, "Testing reflection");
}
}
}
And here's the self-defined InputManipulation class
public class InputManipulation {
Integer total;
public InputManipulation(){this.total = 0;}
public void add(Integer num){this.total += num;}
public void add(String str){System.out.println(str);}
}
Thanks in advance!
I now changed the Test class as follows.. but the problem still exists.
public class Test {
public static void main(String[] args){
Test testExample = new Test();
testExample.testMethod("String1", 1, "String2");
}
public void testMethod(Object... inputs){
InputManipulation test = new InputManipulation();
for (Object input: inputs){
Class ownerClass = test.getClass();
Class inputClass = input.getClass();
Method method = ownerClass.getDeclaredMethod("add", inputClass);
method.invoke(test, "Testing reflection");
}
}
}
I also tried putting the inputClass into an array of Class, as suggested by another post, but it didn't help..
There seems to be a few issues with the initial code you provided and as others have suggested using an IDE would have pointed some of the issues out pretty quickly. However, I have taken your update and fixed the code to call the proper method in the loop you provided of input types.
First change your InputManipulation class like so:
public class InputManipulation {
Integer total;
public InputManipulation() {
this.total = 0;
}
public void add(Integer num) {
this.total += num;
System.out.println(this.total);
}
public void add(String str) {
System.out.println(str);
}
}
Now alter your Test class like so:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) {
Test testExample = new Test();
testExample.testMethod("String1", 1, "String2");
}
public void testMethod(Object... inputs){
InputManipulation test = new InputManipulation();
for (Object input: inputs){
Class<? extends Object> ownerClass = test.getClass();
Class<? extends Object> inputClass = input.getClass();
//Method method; //not needed
try {
ownerClass.getDeclaredMethod("add", inputClass).invoke(test, input);
} catch (NoSuchMethodException | SecurityException |
IllegalAccessException | IllegalArgumentException |
InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
I used these readings to help guide my answer, but altered the way I invoked the method:
http://tutorials.jenkov.com/java-reflection/methods.html
public class Test {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Test testExample = new Test();
testExample.testMethod("String1", 1, "String2");
}
public void testMethod(Object... inputs) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
InputManipulation test = new InputManipulation();
for (Object input: inputs){
Class ownerClass = test.getClass();
Class inputClass = input.getClass();
Method method = ownerClass.getDeclaredMethod("add", inputClass);
method.invoke(test, input);
}
}
}
Your problem was caused by this method.invoke(test, "Testing reflection");
You iterate through 2 types of arguments and depends of this argument you invoke method 'add'. When you tried to invoke method with argument Integer you pass to method String parameter that causes error
I have deal with one problem while accessing arraylist element in another class. I have 2 classes: class A and class B.
class A {
private ArrayList<String> temp=new ArrayList<String>();
temp.add("abc");
temp.add("XYZ");
public ArrayList<String> getTemp() {
return this.temp;
}
}
public class B
{
private A a=null;
public b(A aa)
{
this.a = aa;
}
System.out.printLn(a.getTemp.size());//output is 2
System.out.printLn(a.getTemp.get(0));//null
}
Why it is giving me null? Please give brief explanation of this.
Here is a working version of what you are trying to achieve:
A.java
In the A class, you should be adding elements to your ArrayList in the constructor:
public class A {
private ArrayList<String> temp=new ArrayList<String>();
public A() {
temp.add("abc");
temp.add("XYZ");
}
public ArrayList<String> getTemp() {
return this.temp;
}
}
B.java
The constructor name should match the class's:
public class B {
private A a=null;
public B(A aa)
{
this.a = aa;
}
}
App.java
public class App {
public static void main(String[] args) {
A a = new A();
System.out.println(a.getTemp().size());
System.out.println(a.getTemp().get(0));
}
}
Output:
2
abc
Your current code won't even compile.
Furthermore, I can guarantee 100% that if by some magic your code were to compile the output of the first printLn would in no way be 2. It would be null. `
**First Of All Your Code Is Not Impossible to run**
You Can't assign value to instance variable directly in side of class without constructor or method so your modified class A must be like
**A.java**
class A {
private ArrayList<String> temp=new ArrayList<String>();
public A()
{
temp.add("abc");
temp.add("XYZ");
}
public ArrayList<String> getTemp()
{
return this.temp;
}
}
OR Like
class A {
private ArrayList<String> temp=new ArrayList<String>();
public A()
{
initialize();
}
public void initialize()
{
temp.add("abc");
temp.add("XYZ");
}
public ArrayList<String> getTemp()
{
return this.temp;
}
}
And Then As per Above Your Class B will Be
**B.java**
class B
{
private A a=null;
public B(A aa)
{
this.a = aa;
}
}
And Then you have to go for main method like
**Temp.java**
public class Temp {
public static void main(String... args)
{
A a = new A();
B b = new B(a);
System.out.println(a.getTemp().size());//output is 2
System.out.println(a.getTemp().get(0));//abc
}
}
I want to create a mock in my setUp method, but define the concrete return values in each test method.. is this somehow possible?
Ex:
private List<Long> list;
#Before
public void setUp() {
when(mock.xxx()).thenReturn(list);
}
#Test
public void testEmptyList() {
list = new ArrayList<Long>();
// method call
}
#Test
public void testWithOneElement() {
list = Arrays.asList(Long.valueOf(125L));
// method call
}
Edit:
Best case i could have is this:
private List<Long> list = new ArrayList<Long>();
#Before
public void setUp() {
when(mock.xxx()).thenReturn(list);
}
#Test
public void testEmptyList() {
// method call
}
#Test
public void testWithOneElement() {
list.add(Long.valueOf(123L));
// method call
}
Since Java passes value by Reference, as long as we do not assign a new list to the list, we can add values, and mock will work with the updated list.
But is this kind of behaviour somehow possible even with the changed ObjectIds? So i mock a method call, but define what to return later?
Ex:
private List<Long> list;
#Before
public void setUp() {
when(mock.xxx()).thenReturn(list);
}
#Test
public void testEmptyArrayList() {
list = new ArrayList<Long>();
// method call
}
#Test
public void testEmptyLinkedList() {
list = new LinkedList<Long>();
// method call
}
You can add when(mock.xxx()).thenReturn(list); to both your testcase separately and not in setUp(). then return emplty list in testEmpty and return list with one element in testWithOneElement
private List<Long> list;
#Before
public void setUp() {
// Other setup here
}
#Test
public void testEmptyList() {
list = new ArrayList<Long>();
when(mock.xxx()).thenReturn(list); // return list with no element
// method call
}
#Test
public void testWithOneElement() {
list = Arrays.asList(Long.valueOf(125L));
when(mock.xxx()).thenReturn(list); // return list with one elemet
// method call
}
So.. after some trial and error, I have made sth like this:
private List<Long> list;
#Before
public void setUp() {
when(mock.xxx()).thenAnswer(
new Answer<List<Long>>() {
#Override
public List<Long> answer(final InvocationOnMock invocation) {
return list;
}
});
}
#Test
public void testEmptyArrayList() {
list = new ArrayList<Long>();
// method call
}
#Test
public void testEmptyLinkedList() {
list = new LinkedList<Long>();
// method call
}
Since we now define in setUp, not "return value", but "the called method which prepares the return value", and since this method will be called at runtime first, we do not get a nullPointer, and the values we assign in each method will be returned.
I am facing problems when using try/catch
I created an exception class called EmptyQueueException that extends from Exception
Unfortunately, Eclipse throws me an error :" Catched expected instead"
public class Testclass {
public static void main(String[] args) {
ArrayQueue arrayy = new ArrayQueue();
try{
arrayy.dequeue();
}
catch(EmptyQueueException s){
// what to do here ?
}
} // end main
} // end testclass
Here is my Exception class:
public class EmptyQueueException extends Exception {
// automatically done by eclipse, what for?
private static final long serialVersionUID = 1L;
public EmptyQueueException() {
}
public EmptyQueueException(String s){
super("Queue is empty");
}
}
This is my dequeue method:
public int dequeue() throws EmptyQueueException {
if (empty()){
throw new EmptyQueueException();
}
int retour = head();
head = ++head % array.length;
return retour;
}
I try to use different instances for my tests but the first one is always used.
During the second test, it's the content of the first instance that is displayed.
I don't know where to look for.
public class MyActivityTest extends
ActivityInstrumentationTestCase2<MyActivity> {
private Solo solo;
public MyActivityTest() {
super(MyActivity.class);
}
protected void setUp() throws Exception {
super.setUp();
Authentication.setSessionId("mysessionid", this.getInstrumentation()
.getTargetContext().getApplicationContext());
solo = new Solo(getInstrumentation(), getActivity());
}
public void testFailFetching() {
CommunicationFactory.setInstance(MyActivityData.FALSE_QUIZCOMM_DEFAULT);
//some Solo tests
}
public void testSucceedFetching() {
CommunicationFactory.setInstance(MyActivity.CORRECT_QUIZCOMM_DEFAULT);
//some Solo tests
}
#Override
protected void tearDown() throws Exception {
CommunicationFactory.setInstance(null);
super.tearDown();
}
}
The setUp() method will be called before each test. Provided it completes without throwing an exception (which presumably would abort your tests anyway), your solo variable is being reconstructed for each test. The follow test code demonstrates this:
public class ExampleTest extends TestCase {
private static int num = 1;
private Foo foo;
#Override
protected void setUp() throws Exception {
super.setUp();
foo = new Foo(num++);
}
public void testA() {
foo.printNum();
}
public void testB() {
foo.printNum();
}
private static class Foo {
private final int num;
public Foo(int num) {
this.num = num;
}
public void printNum() {
System.out.println(num);
}
}
}
This prints:
1
2
It's possible the Solo objects equal each other in the separate tests. But they won't be the same object.