1

I have a class with some fields:

class User {
  String name;
  String id;
  // other fields
}

I'm getting a user from the service and want to assert that name and id fields are not empty. The object contains other fields, but those are not needed for this particular case. I tried to extract required fields and apply the allSatisfy {} function:

User user = service.getUser();
assertThat(user)
  .extracting("name", "id") // extract only those fields that I need for now
  .allSatisy { field -> assertThat(field).isNotEmpty() } // this doesn't compile because `field` is not a String

Am I using the extracting() function wrong? Or is there other way of asserting multiple fields of an object at once instead of asserting each field separately?

Vitali Plagov
  • 722
  • 1
  • 12
  • 31
  • 2
    Still not used assertj but I would assume that `extracting` would only hold Object-s. So `assertThat((String)field).isNotEmpty()`. – Joop Eggen Sep 30 '21 at 09:45

1 Answers1

3

Joop Eggen suggestion is a good solution, extracting multiple values at once returns the list of extract values wrapped in a ListAssert object so that you can (List) chain assertions. The list is a list of object because there is no way to know what type the list will contain (id could be an Integer and name a String so you can't assume you will be given a list of string here).

You can try asIntanceOf to narrow the type as you know more than AssertJ in this case, ex:

assertThat(user)
  .extracting("name", "id")
  .asInstanceOf(InstanceOfAssertFactories.list(String.class))
  .allSatisy(field -> assertThat(field).isNotEmpty());

Whether it is better than casting the field, I'm not completely sure, I leave it to you to decide.

- Edit -

I tried your example and it worked fine with assertj core 3.21.0, this test is passing:

@Test
void test() {
    User user = new User();
    user.name = "Joe";
    user.id = "123";
    assertThat(user).extracting("name", "id")
                    .asInstanceOf(InstanceOfAssertFactories.list(String.class))
                    .allSatisfy(field -> assertThat(field).isNotEmpty());
}

So I guess this has to do with Kotlin.

Joel Costigliola
  • 6,308
  • 27
  • 35
  • Thanks for the answer! I tried the `asInstanceOf()` to set the type, but didn't know it is possible to use `InstanceOfAssertFactories.list(String.class)`. So, I tried this construction, but there's an import ambiguity with the `allSatisfy`: Overload resolution ambiguity. All these functions match. * public open fun allSatisfy(requirements: Consumer!): ListAssert! defined in org.assertj.core.api.ListAssert * public open fun allSatisfy(requirements: ThrowingConsumer!): ListAssert! defined in org.assertj.core.api.ListAssert – Vitali Plagov Sep 30 '21 at 22:07
  • Thanks for the feedback, I did not try my suggestion so I was not 100% sure if generics would get in the way which it seems it does. I'll give it a try to see if I can make it work. – Joel Costigliola Oct 01 '21 at 01:04
  • I used `allMatch{}` instead and it works. – Vitali Plagov Oct 01 '21 at 06:25