1

I am currently writing a JUnit Unit Test Case for a simple method. Here is the method in question:

public static Integer[] findUnpairedNumbers(Integer[] numbers) {
    // catches if passed array is empty or uninitialized 
    if (numbers == null) {
        throw new IllegalArgumentException();
    }
    // HashSet initialized to store unpaired numbers
    HashSet<Integer> result = new HashSet<Integer>();
    // Loop through numbers array
    for (int next: numbers) {
        // if HashSet already contains next element, remove that element from the HashSet
        if (result.contains(next)) {
            result.remove(next);
        }
        // Otherwise, add it to the HashSet
        else {
            result.add(next);
        }
    }
    // return the HashSet of unpaired numbers, converting to back to Integer array
    return result.toArray(new Integer[result.size()]);
}

Here is the JUnit test I have written:

package program;

import static org.junit.Assert.*;

import org.junit.Test;

public class FindUnpairedTest {

    @Test
    public void test() {
        Integer[] numbers = {1, 2, 4, 5, 7, 7, 8, 8, 9, 1, 5};
        Integer[] unpairedCheck = {2, 4};
        Integer[] unpaired = findUnpairedNumbers(numbers);

        if (unpaired != unpairedCheck) {
            fail();
        }
    }
}

However, the findUnpairedNumbers class is not recognized by the test class. It is in the same package. Do I need to import anything else? Where am I going wrong here?

Also please let me know if any syntax is unorthodox or if there are other ways I can improve my test case.

5
  • Have you added JUnit library to your classpath? Commented Mar 18, 2016 at 20:45
  • I have yes. I've written JUnit tests before, but for very different things. The simplicity of this one is confusing me I guess. Commented Mar 18, 2016 at 20:46
  • Ok, 1. you should create an object to call the method you want to test in the testClass then call the method obj.findUnpairedNumbers() or 2. you should make the method being called as static and call YourClass.findUnpairedNumbers() Commented Mar 18, 2016 at 20:49
  • Side note: you should spend more time reading the compiler error messages. The java compiler is very good in pointing out what is wrong in source code. Far too often, one does not need Stackoverflow to understand an error. One just needs the discipline to read error messages word by word; turning the line that is pointed out by the compiler, and read that ... word by word.
    – GhostCat
    Commented Mar 18, 2016 at 20:55
  • findUnpairedNumbers is a method, not a class... you do have this method in a class, right? If it's not in the same package as the test class you will need to reference it using the full class name as well.
    – cjstehno
    Commented Mar 19, 2016 at 17:00

2 Answers 2

3

However, the findUnpairedNumbers class is not recognized by the test class. It is in the same package. Do I need to import anything else?

findUnpairedNumbers is a static method of some class. In order to call it, you must specify in what class it exists.

Like this:

Integer[] unpaired = NameOfTheClass.findUnpairedNumbers(numbers);

The test method

Also please let me know if any syntax is unorthodox or if there are other ways I can improve my test case.

Don't use fail() directly. Usually, we call a assertSomething() method from JUnit (e.g. assertEquals()) at the assertion phase of our test. In your case, I suggest assertArrayEquals():

@Test
public void test() {
    Integer[] numbers = {1, 2, 4, 5, 7, 7, 8, 8, 9, 1, 5};
    Integer[] unpaired = findUnpairedNumbers(numbers);

    Integer[] expectedUnpaired = {2, 4};
    assertArrayEquals(expectedUnpaired, unpaired);
}

Notice how the test becomes cleaner. I also suggest you rename your test method name to something more descriptive of the behavior:

@Test
public void findUnpairedNumbersLeavesOnlyNumbersWithoutPairs() { ...

This would make it easier for maintainers to get the intent of the test and the expected behavior (in case it fails in the future).


More on the static problem

A more complete explanation/example:

Say the findUnpairedNumbers method belongs to a class called FindUnpaired:

package program;
public class FindUnpaired {
    public static Integer[] findUnpairedNumbers(Integer[] numbers) {
        ...
        return result.toArray(new Integer[result.size()]);
    }
}

Now, in your test class you can use it:

package program;
import static org.junit.Assert.*;
import org.junit.Test;
public class FindUnpairedTest {
    @Test
    public void test() {
        Integer[] numbers = {1, 2, 4, 5, 7, 7, 8, 8, 9, 1, 5};
        Integer[] unpairedCheck = {2, 4};
        Integer[] unpaired = FindUnpaired.findUnpairedNumbers(numbers);
//                           ^^^^^^^^^^^^----------------------------------- changed here
        if (unpaired != unpairedCheck) {
            fail();
        }
    }
}

Other considerations:

  • You can use FindUnpaired directly because we are assuming the test class is at the same package. If the packages were different, you'd have to import FindUnpaired at the test class.

    package someOtherPackage;
    import program.FindUnpaired;
    public class FindUnpairedTest {
    
  • Another option is to use a static import of the findUnpairedNumbers method. If you follow this route, you don't need to prefix when calling it (call it like it was a static method declared in the current class).

    import static program.FindUnpaired.findUnpairedNumbers; // static import
    public class FindUnpairedTest {
        ...
        Integer[] unpaired = findUnpairedNumbers(numbers); // no need to prefix
    
2
  • Oh wow. I can't believe I missed that. Thank you! The test is running now (albeit failing) and I'll hammer it out. Thank you! Commented Mar 18, 2016 at 20:49
  • You might want to add the other option: using a static import for the method; avoiding the need to put the class name in front of the invocation.
    – GhostCat
    Commented Mar 18, 2016 at 20:53
0
  1. you should create an object to call the method you want to test in the testClass then call the method obj.findUnpairedNumbers()

or

  1. you should make the method being called as static and call YourClass.findUnpairedNumbers()
2
  • Side note: always check carefully what people are doing in their code. His method is already static.
    – GhostCat
    Commented Mar 18, 2016 at 20:56
  • agree. It's better to give the actual answer to the code than to give generic answers. Commented Mar 18, 2016 at 20:57

Not the answer you're looking for? Browse other questions tagged or ask your own question.