2

I am new to unit testing. I am testing a function that "tokenizes" a String. The String is a mathematical expression. Here is my code:

@Test
public void testTokenizer() throws InvalidExpressionException {

    final String QUERY = "sin(x) / 5*x";
    final String[] EXPECTED = {"x", "sin", "5", "x", "*", "/"};
    parser.parse(QUERY);
    final String[] actual = parser.getTokens().toArray(new String[parser.getTokens().size()]);

    Assertions.assertEquals(EXPECTED, actual);
}

This is the error I get:

org.opentest4j.AssertionFailedError: 
Expected :[Ljava.lang.String;@62043840
Actual   :[Ljava.lang.String;@5315b42e

I am using junit5. It looks like those are memory addresses(I'm a beginner). Am I making the wrong assertion(comparing pointers or something)?

defoification
  • 315
  • 6
  • 18

2 Answers2

4

Use Assert.assertArrayEquals for arrays comparitions, you are comparing the ids from the objects

import org.junit.Assert;

@Test
public void testTokenizer() throws InvalidExpressionException {

    final String QUERY = "sin(x) / 5*x";
    final String[] EXPECTED = {"x", "sin", "5", "x", "*", "/"};
    parser.parse(QUERY);
    final String[] actual = parser.getTokens().toArray(new String[parser.getTokens().size()]);

    Assert.assertArrayEquals( EXPECTED, actual );
}
developer_hatch
  • 15,898
  • 3
  • 42
  • 75
3

Those aren't memory addresses, they're object identifiers that contain hash codes of the objects. The toString method of arrays returns the array's object identifier.

http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#toString-- "The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object."

The array version includes a few extra characters to show that it's an array.

Your method under test didn't return the expected value. That's because you have two different arrays, and arrays are only equal by identity, not contents. So they cannot be equal unless they are the exact same array object. You need to assert that the array contents compare equal.

Incidentally, the variable name EXPECTED violates the Java naming conventions because all upper-case with underscores is reserved for constant variable names, or at least variables that point to immutable objects.

If you aim for the assertion message to show the arrays' contents, add an assertion message argument that shows that.

Lew Bloch
  • 3,364
  • 1
  • 16
  • 10
  • thanks for the extra info, I appreciate it. Isn't `final` the same thing as `const`, or should I really change it from all uppercase? – defoification Jun 10 '17 at 00:21
  • `const` isn't a thing in Java. Strictly speaking, that is, according to the Java Language Specification (JLS), a _constant variable_ is a variable of type `String` or a primitive type that is initialized with a _constant expression_. It gets special compiler treatment. Some people extend the notion to references to immutable objects, which do not get that special treatment, but no way can a mutable object be considered constant. The Java conventions call for constants to get upper-case variable names, some people extend that to immutable objects, but mutable objects? Bad idea! – Lew Bloch Jun 10 '17 at 02:42
  • 1
    Fantastic answer by the way :), is a plus one in my opinion – developer_hatch Jun 10 '17 at 02:51
  • I'm still laughing... comparitions haahahah... – developer_hatch Jun 10 '17 at 02:53