Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using 'extracting' with InstanceOfAssertFactory will lead to an unexpected AssertionError if the extracted value is null #3266

Open
kamil-sita opened this issue Nov 21, 2023 · 5 comments
Labels
status: team discussion An issue we'd like to discuss as a team to make progress

Comments

@kamil-sita
Copy link

Describe the bug
AssertJ allows extracting values from the original object using "extracting" method in order to test them in a more fluent way. AssertJ also allows using InstanceOfAssertFactory in "extracting" to specify which assertions should be used to test the extracted value.

However, there's an unexpected non-null check when using InstanceOfAssertFactory, which leads to an exception being thrown if the extracted value is null. This is not the case when not using InstanceOfAssertFactory, see the example below:

import org.assertj.core.api.InstanceOfAssertFactories;
import org.testng.annotations.Test;

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

public class Reproduced {

    @Test
    public void should_testNullCorrectly() {
        // given
        StringHolder holder = new StringHolder(null);

        // then
        assertThat(holder)
            .extracting(StringHolder::value)
            .isNull(); // this test will succeed
    }

    @Test
    public void should_testNullCorrectlyWithAssertFactory() {
        // given
        StringHolder holder = new StringHolder(null);

        // then
        assertThat(holder)
            .extracting(StringHolder::value, InstanceOfAssertFactories.STRING)
            .isNull(); // this test will fail
    }

    public record StringHolder(String value) { }
}
  • assertj core version: tested with 3.16.1 and 3.24.2
  • java version: 17.0.6
  • test framework version: tested with TestNG 6.9.10 and JUnit 5.9.2

Test case reproducing the bug

import org.assertj.core.api.InstanceOfAssertFactories;
import org.testng.annotations.Test;

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

public class Reproduced {

    @Test
    public void should_testNullCorrectlyWithAssertFactory() {
        // given
        StringHolder holder = new StringHolder(null);

        // then
        assertThat(holder)
            .extracting(StringHolder::value, InstanceOfAssertFactories.STRING)
            .isNull(); // this test will fail
    }

    public record StringHolder(String value) { }
}
@scordio
Copy link
Member

scordio commented Nov 21, 2023

extracting(Function, InstanceOfAssertFactory) internally relies on asInstanceOf which performs a preliminary isInstanceOf check, the source of the AssertionError you are experiencing.

Is there a reason why you are using InstanceOfAssertFactories.STRING even though you already expect the value to be null?

On a side note, the Javadoc of extracting and asInstanceOf could be improved to cover such cases.

@kamil-sita
Copy link
Author

Is there a reason why you are using InstanceOfAssertFactories.STRING even though you already expect the value to be null?

Not exactly, no. I have created helper methods for exporting properties of the objects I'm testing, like this:

public AbstractStringAssert<?> assertionForPropertyXyz() {
   // some complicated code I would prefer not to repeat tens of times
   
   return assertThat(abc)
       .extracting(Abc::getXyz, InstanceOfAssertFactories.STRING);
}

and have planned to use them in my code like so:

// test 1
   someObject.assertionForPropertyXyz().startsWith("lorem ipsum");
// test 2
   someObject.assertionForPropertyXyz().isNull();

I realize that it might be an uncommon approach, however I also think that having extracting methods behave differently here is very surprising. Personally I think that both should behave in more-or-less the same way.

@kamil-sita kamil-sita changed the title Using 'extracting' with InstanceOfAssertFactory will lead to an unexpected AssertionError if extraced value is null Using 'extracting' with InstanceOfAssertFactory will lead to an unexpected AssertionError if the extracted value is null Nov 21, 2023
@scordio
Copy link
Member

scordio commented Nov 21, 2023

It's a fair request 🙂 However, we need a more comprehensive analysis of what this change would mean, especially because we expose some more generic versions of extracting for third-party extensions.

We'll discuss it internally and get back to you.

@scordio scordio added the status: team discussion An issue we'd like to discuss as a team to make progress label Nov 21, 2023
@kamil-sita
Copy link
Author

Thank you!

@kamil-sita
Copy link
Author

Hi, I wonder if you had an occasion to discuss this issue internally?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: team discussion An issue we'd like to discuss as a team to make progress
Projects
None yet
Development

No branches or pull requests

2 participants