Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I check that no value is null after calling extracting on a list of objects?

Tags:

java

assertj

Using AssertJ in a unit test, I want to extract several properties of a custom object from a list of such objects via extracting and check if they are all non-null.

For example, assuming I want to extract fieldA and fieldB of MyObject:

import static from org.assertj.core.api.Assertions.assertThat;

List<MyObject> theList = ...; 
assertThat(theList).extracting("fieldA", "fieldB")).isNotNull();

I am having trouble figuring out what is being checked.

Is isNotNull checking that:

  1. the iterable returned by extracting is not null?
  2. no tuples in the list are null?
  3. every value in every tuple is not null?
like image 622
gph Avatar asked Sep 07 '25 17:09

gph


2 Answers

Following your example:

assertThat(theList).extracting("fieldA", "fieldB").isNotNull();

isNotNull only checks that the Iterable of tuples returned by extracting is not null.

flatExtracting + doesNotContainNull

To check that none of the extracted values are null, you can use flatExtracting and doesNotContainNull:

assertThat(theList).flatExtracting("fieldA", "fieldB").doesNotContainNull();

which yields a message like the following in case of failures:

java.lang.AssertionError: 
Expecting actual:
  ["value1", "value2", null, "value4"]
not to contain null elements

Due to the flattened nature of the solution, there is no indication of which object caused the failure but can be identified by counting the pairs in the displayed actual.

extracting + noneMatch

The complexity can be increased for clearer error messages:

assertThat(theList).extracting("fieldA", "fieldB").noneMatch(tuple -> tuple.toList().contains(null));

which yields in case of failure:

java.lang.AssertionError: [Extracted: fieldA, fieldB] 
Expecting no elements of:
  [("value1", "value2"), (null, "value4")]
to match given predicate but this element did:
  (null, "value4")

extracting + allSatisfy + doesNotContainNull

Another option for clearer error messages:

assertThat(theList).extracting("fieldA", "fieldB").allSatisfy(tuple -> assertThat(tuple.toList()).doesNotContainNull());

which yields in case of failure:

java.lang.AssertionError: [Extracted: fieldA, fieldB] 
Expecting all elements of:
  [("value1", "value2"), (null, "value4")]
to satisfy given requirements, but these elements did not:

(null, "value4")
error: 
Expecting actual:
  [null, "value4"]
not to contain null elements
like image 77
Stefano Cordio Avatar answered Sep 10 '25 05:09

Stefano Cordio


When you use the following methods it is checking if the theList is not null and not each of the objects inside the list.

List<MyObject> theList = ...; 
assertThat(theList).extracting("fieldA", "fieldB")).isNotNull();

In fact you are extracting the values of fieldA and fieldB which are your object icuding a pair of values, so theList itself is not null which is returned by isNotNull() method.

I have prepared a simple example to make sure that every value in a pair is not null as well.

    import static org.assertj.core.api.Assertions.assertThat;
    import java.util.Arrays;
    import java.util.List;
public class test {
     static class MyObject {
            String fieldA;
            String fieldB;

            public MyObject(String fieldA, String fieldB) {
                this.fieldA = fieldA;
                this.fieldB = fieldB;
            }

            // Getter methods for fieldA and fieldB
            public String getFieldA() {
                return fieldA;
            }

            public String getFieldB() {
                return fieldB;
            }
        }

        public static void main(String[] args) {
            List<MyObject> theList = Arrays.asList(
                new MyObject("valueA1", "valueB1"),
                new MyObject("valueA2", "valueB2"),
                new MyObject("valueA3", "valueB3"),
                new MyObject(null, "valueB4"),  
                new MyObject("valueA5", null)  
            );

            try {
                assertThat(theList).extracting(MyObject::getFieldA).doesNotContainNull();
                System.out.println("Assertion for fieldA passed.");
            } catch (AssertionError e) {
                System.out.println("Assertion for fieldA failed: " + e.getMessage());
            }

            try {
                assertThat(theList).extracting(MyObject::getFieldB).doesNotContainNull();
                System.out.println("Assertion for fieldB passed.");
            } catch (AssertionError e) {
                System.out.println("Assertion for fieldB failed: " + e.getMessage());
            }
        }
}

As you see in the picture below, this way you can even determine which element caused a failure: fieldA or fieldB.

enter image description here

like image 24
Shila Mosammami Avatar answered Sep 10 '25 05:09

Shila Mosammami