0

I have written integration test which receives a xml document from queue, and create a object out of it which will be persisted in database. Now to be thorough in my test, I want to check all the fields that are populated by the xml i.e. around 20 fields. I wrote assert statement for each field.

assertTrue (payload.shipmentNo == object.shipmentNo)
assertTrue (payload.shipmentEMEA.location == object.shipmentLocationMap.get(SHIPMENT_EMEA.toString()))
assertTrue (payload.shipmentAMER.location == object.shipmentLocationMap.get(SHIPMENT_AMER.toString()))
assertTrue (payload.shipmentAPAC.location == object.shipmentLocationMap.get(SHIPMENT_APAC.toString()))
assertTrue (payload.shipmentVersion == object.shipmentVersion)
assertTrue (payload.shipmentSourceId == object.shipmentSourceId )
assertTrue (payload.noOfItemsInShipment == object.noOfItemsInShipment)
assertTrue (payload.shipmentName == object.shipmentName)
assertTrue (payload.shipmentDate == object.shipmentDate)
assertTrue (payload.shipmentOwnerID == String.valueOf(object.shipmentOwnerID))
assertTrue (payload.shipmentClass == object.shipmentClass)
assertTrue ('STARTED' == object.status)

But I am advised to use single assert statement in by testcase. I have been wondering how would I be able to do that, one way to achieve is to write an if block from which return true only if all the values match with the xml but in that case I loose the ability to know exactly which field is failing. Any ideas how can i achieve both things i.e. we have single assert + I get to know exactly which field failed.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Ambuj Jauhari
  • 1,187
  • 4
  • 26
  • 46
  • 5
    "But i am advised to use single assert statement in by testcase" you were advised badly – Raedwald Apr 05 '16 at 11:30
  • Bad does not begin to cover it. Are you sure this person is not after your job? – Gimby Apr 05 '16 at 11:35
  • 4
    The rule that each test case should have only one assert [is foolish](http://stackoverflow.com/a/20300843/545127). – Raedwald Apr 05 '16 at 11:35
  • Normally it is advised to have a single class for the Integration Test. But you can have multiple test cases and asserts. I don't understand the reason for you being advised as such. – user2004685 Apr 05 '16 at 11:36
  • As @Raedwald says, the advice is foolish, but in addition, it's specific for unit tests. In [Test Desiderata](https://kentbeck.github.io/TestDesiderata/), Kent Beck describes unit tests versus acceptance tests as making a tradeoff between specificity of a test verus it's readability (and I would argue its "inspiring" desiderata). Integration tests like the one you describe seem to me an example of an acceptance test. – Jake Stevens-Haas Jun 25 '21 at 22:56

3 Answers3

1

"Using a single assert statement" is a good practice in terms that you are testing a single rule. That prevents you from writing a "mega-test" that checks too much things.

So, should you write a single assert statement? Well, yes, you should. BUT this is a recommendation. When testing you have to make sure that every test tests a single feature. If your feature does several things (maybe you should think again and refactor in several features) then several asserts per test seems OK to me.

As a rule, think this:

When writing tests each test should test a single feature under different circumstances

Also, if several asserts improve readability, go on with them

Alberto S.
  • 7,409
  • 6
  • 27
  • 46
0

In case of java you can use assertj fluent assertions:

http://joel-costigliola.github.io/assertj/

For example you can compare objects using:

assertThat(payload).isEqualToComparingFieldByField(object);

You can use other method apis which can exclude or include specified fields

wsl
  • 8,875
  • 1
  • 20
  • 24
  • i thought of that, but i have to check status must be 'STARTED' plus payload's every field does not has the same name as object, for e.g. shipmentLocationMap – Ambuj Jauhari Apr 05 '16 at 12:04
  • Yep, at the beginning I thought that there are same objects. – wsl Apr 05 '16 at 12:20
0

I use that and find it very useful.

import static org.junit.jupiter.api.Assertions.assertAll;

assertAll(
    () -> assertThat(actual1, is(expected)),
    () -> assertThat(actual2, is(expected))
);
Svetopolk
  • 337
  • 5
  • 14