2

It seems there is a very silly mistake somewhere as the following hello-world program is not working for me.

import com.google.common.io.BaseEncoding;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

String hello = "hello";
junit.framework.Assert.assertEquals(
    hello.getBytes(),
    BaseEncoding.base64().decode(
            BaseEncoding.base64().encode(hello.getBytes())
    )
);

I even tried hello.getBytes("ISO-8859-1")

What am I missing?

jpaugh
  • 6,634
  • 4
  • 38
  • 90
user2250246
  • 3,807
  • 5
  • 43
  • 71
  • 4
    Two byte arrays, even if they contain the same values, are not equal. There is an assertion verifying that two arrays are equal, but JUnit 3 is so old that I can't remember the name of the method. Probably something like `assertArrayEquals()`. – JB Nizet May 02 '16 at 19:35
  • 1
    Definitely agree this is more likely to be incorrect usage of JUnit than incorrect usage of Guava. – Louis Wasserman May 02 '16 at 19:44
  • 1
    Good idea explicitly specifying the charset, that's a common source of bugs. In both `.getBytes()` and (if you use it) `new String()` you should always specify a charset explicitly. The [`StandardCharsets`](https://docs.oracle.com/javase/8/docs/api/java/nio/charset/StandardCharsets.html) class makes this easy - just use `UTF_8` everywhere a charset is expected and you'll (almost) never go wrong. – dimo414 May 03 '16 at 02:29

2 Answers2

5

Arrays (confusingly) do not override Object.equals() (similarly they don't override .toString(), which is why you see those useless \[Lsome.Type;@28a418fc strings when you print an array), meaning that calling .equals() on two equivalent arrays will not give you the result you'd expect:

System.out.println(new int[]{}.equals(new int[]{}));

This prints false. Ugh. See Effective Java Item 25: Prefer lists to arrays for more.

Instead you should use the static helper functions in the Arrays class to do these sort of operations on arrays. For example this prints true:

System.out.println(Arrays.equals(new int[]{}, new int[]{}));

So try Arrays.equals() or JUnit's Assert.assertArrayEquals() instead of Assert.assertEquals():

junit.framework.Assert.assertArrayEquals(
    hello.getBytes(),
    BaseEncoding.base64().decode(BaseEncoding.base64().encode(hello.getBytes())
    )
);

This should behave as expected.

Community
  • 1
  • 1
dimo414
  • 47,227
  • 18
  • 148
  • 244
3

If you instead check if the String matches then it does match.

        junit.framework.Assert.assertEquals(
            hello,
            new String(
                    BaseEncoding.base64().decode(
                            BaseEncoding.base64().encode(hello.getBytes())
                    )
            ));

What your check is looking at is the address, I do not know why. If you look at the values in the byte[]'s you see they match.

        System.out.println("hello.getBytes = " + Arrays.toString(hello.getBytes()));
    System.out.println("decoded = " + Arrays.toString(BaseEncoding.base64().decode(
            BaseEncoding.base64().encode(hello.getBytes())
    )
    ));

which outputs:

hello.getBytes = [104, 101, 108, 108, 111]
decoded = [104, 101, 108, 108, 111]
Jose Martinez
  • 11,452
  • 7
  • 53
  • 68