DarthVader
DarthVader

Reputation: 55022

Unit testing with assertTrue vs others

I work in a TDD environment and I use assertTrue a lot whereas there are many other methods, such as assert equals etc. I have a class that I have more than 40 test cases and they are all assertTrue. is this acceptable?

I wanted to ask as a style, is this proper?

any suggestions?

if u think this question is inappropriate let me know i ll delete it.

EDIT:

    assertTrue(targetSpecifiers.size() == 2);
    assertTrue(targetSpecifiers.get(0).getPlacementId().compareTo(new BigInteger("1")) ==0);
    assertTrue(targetSpecifiers.get(1).getPlacementId().compareTo(new BigInteger("2")) ==0);

Upvotes: 4

Views: 1282

Answers (4)

Kkkev
Kkkev

Reputation: 4895

These assertions are perfectly valid, but other assertions are easier to read and deliver better failure messages.

I recommend looking at Hamcrest- this provides the most readable form of assertions and failure messages. Your example of

assertTrue(targetSpecifiers.size() == 2);
assertTrue(targetSpecifiers.get(0).getPlacementId().compareTo(new BigInteger("1")) ==0);
assertTrue(targetSpecifiers.get(1).getPlacementId().compareTo(new BigInteger("2")) ==0);

could be rewritten as

assertThat(targetSpecifiers, hasSize(2));
assertThat(targetSpecifiers.get(0).getPlacementId(), equalTo(BigInteger.valueOf(1));
assertThat(targetSpecifiers.get(1).getPlacementId(), equalTo(BigInteger.valueOf(1));

or even more succinctly as

assertThat(targetSpecifiers, contains(
    hasProperty("placementId", equalTo(BigInteger.valueOf(1)),
    hasProperty("placementId", equalTo(BigInteger.valueOf(2))
);

contains verifies completeness and order, so this covers all three assertions.

Upvotes: 2

mikej
mikej

Reputation: 66263

The main benefits of using other assertions is that they better communicate intent and are likely to give a more meaningful default message in the event of failure.

e.g.

if you write assertEquals(2, x) if x is actually 1 then the failure message will be:

java.lang.AssertionError: expected:<2> but was:<1>

which is more helpful than if you write assertTrue(x == 2) where all you would see is the AssertionError and the stack trace.

This is even more important when you are using TDD because you when you write a failing test first you want to be confident that the test is failing for the reason you are expecting it to and that there is not some accidental behaviour going on.

Upvotes: 6

Aravind Yarram
Aravind Yarram

Reputation: 80166

Where appropriate you should use the correct assertXXX methods as they improve the reporting of failures. For e.g. if you are testing for the equality of let us say 2 string "abc" (expected) and "abxy" (actual), then the use of assertEquals

assertEquals("abc", "abxy") 

will provide a better output that is easier to reason about than using the assertTrue like below

assertTrue("abc".equals("abxy"))

NOTE: Also pay attention to where you are specifying the actual and expected arguments. I see lot of developers not following the convention (junit's convention) that the expected should be the first param to the assertXXX methods. Improper usage also leads to lot of confusion

Upvotes: 5

Jon Skeet
Jon Skeet

Reputation: 1499800

My guess is that you've got things like:

assertTrue(expectedValue.equals(actualValue));

That will still test the right thing - but when there's a failure, all it can tell you was that the assertion failed. If you used this instead:

assertEquals(expectedValue, actualValue);

... then the failure will say "Expected: 5; Was: 10" or something similar, which makes it considerably easier to work out what's going on.

Unless you're asserting the result of a method returning boolean or something like that, I find assertTrue to be pretty rarely useful.

If you could give examples of your assertions, we may be able to translate them into more idiomatic ones.

Upvotes: 4

Related Questions