Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using toString() for unit testing in Java

In a unit test, is it generally a good idea to test returned values according to the string their toString() returns?

For example, doing the following to make sure the expected list is returned:

 assertEquals(someExpression.toString() ,"[a, b, c]");

It seems to me that the considerations are as follows:

Pros: Saving time (constructing the actual expected value requires longer code).

Cons: The test depends on toString(), which is not formally defined in the doc, and thus can change in any future version.

like image 384
Ofer Avatar asked Sep 28 '26 14:09

Ofer


2 Answers

The only time that I would test on toString() of an object is when I have an uneditable class that did not implement hashcode or equals, but instead implemented a toString() to output its field's content. Even then, I won't use a hardcoded string as the equality test, but instead do something like

SomeObject b = new SomeObject(expected, values, here);
assertEquals(a.toString(), b.toString());

Your approach might save time initially, but in the long run it would take far more time just to maintain the test since you are hardcoding the string of the expected result of the toString().

Edit 1: Naturally, if you are testing a function / process that outputs a string, that would be one of the times you should be using a hardcoded string as the expected result.

String input = "abcde";
String result = removeVowels(input);
assertEquals(result, "bcd");
like image 168
Kree Avatar answered Oct 01 '26 03:10

Kree


The Assert.assertThat() method has matchers specific to collections and much more.

For instance, contains() works for collections:

List<String> someExpression = asList("a", "b", "c");
assertThat(someExpression.toString(), contains("a", "b", "c"));

The advantages are:

  • You don't need to implement .toString();
  • when the test fails, the error message is pretty descriptive, it will say "Expected collection containig 'b' and didn't find it."

Try:

import static org.junit.Assert.assertThat;
import static org.hamcrest.Matchers.contains;
import static java.util.Arrays.asList;

List<String> someExpression = asList("a", "c");
assertThat(someExpression.toString(), contains("a", "b", "c"));
like image 25
acdcjunior Avatar answered Oct 01 '26 03:10

acdcjunior