Skip to content

DefaultArgumentConverter no longer converts "null" to false #3472

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

Closed
1 task
JKomoroski opened this issue Sep 19, 2023 · 9 comments
Closed
1 task

DefaultArgumentConverter no longer converts "null" to false #3472

JKomoroski opened this issue Sep 19, 2023 · 9 comments

Comments

@JKomoroski
Copy link

JKomoroski commented Sep 19, 2023

Error message: Failed to convert String "null" to type java.lang.Boolean

Working Version: 5.9.2
Broken Version: 5.10.0

Steps to reproduce

Use the DefaultArgumentConverter to convert a string to a Boolean. Strings "true" and "false" convert correctly, but the string "null" no longer converts to a null Boolean (wrapper type) after upgrading.

Since this converter is used for @CsvSource data in @ParameterizedTest methods , it is quite common to include nulls in those sources for many types, not just Boolean.class.

A naive fix and test for this issue is included in my fork of junit5. I suspect a more robust fix for nullable types more broadly should be considered.

main...JKomoroski:junit5:main

Deliverables

  • Fix behavior of nullable wrapper types to support "null" -> null conversions once again.
@JKomoroski JKomoroski changed the title String to Boolean DefaultArumentConverter Broken After Update from 5.9.2 to 5.10.0 String to Boolean DefaultArgumentConverter Broken After Update from 5.9.2 to 5.10.0 Sep 19, 2023
@sbrannen
Copy link
Member

This is now the expected behavior due to #3177.

However, we may consider a way to switch back to lenient parsing of boolean values or make the true/false values somehow configurable.

@sbrannen sbrannen changed the title String to Boolean DefaultArgumentConverter Broken After Update from 5.9.2 to 5.10.0 DefaultArgumentConverter no longer treats "null" as false Sep 21, 2023
@sbrannen sbrannen changed the title DefaultArgumentConverter no longer treats "null" as false StringToBooleanConverter no longer treats "null" as false Sep 21, 2023
@JKomoroski
Copy link
Author

@sbrannen I'm not sure this title change accurately reflects the behavior change.

In the past "null" was being converted to null for nullable primate wrapper types (Boolean.class in this case). The new issue title indicates that the issue was expecting "null" -> false for a boolean primitive which is not the issue I'm having.

@sbrannen
Copy link
Member

sbrannen commented Sep 22, 2023

In the past "null" was being converted to null for nullable primate wrapper types (Boolean.class in this case).

My initial tests do not reveal that, but perhaps I am missing something.

Previously, we used Boolean::valueOf to convert a String to a Boolean, and that method returns false for "null". It also returns false for null.

The new issue title indicates that the issue was expecting "null" -> false for a boolean primitive which is not the issue I'm having.

If I'm not mistaken, we previously converted "null" to Boolean.FALSE or false for Boolean and boolean target types, respectively.

Based on that, this is technically a regression, but I don't yet know if we will "fix" this regression.

In any case, I'll introduce more extensive testing around this.

@sbrannen sbrannen self-assigned this Sep 22, 2023
@sbrannen sbrannen added this to the 5.10.1 milestone Sep 22, 2023
@sbrannen sbrannen changed the title StringToBooleanConverter no longer treats "null" as false DefaultArgumentConverter no longer treats "null" as false Sep 22, 2023
@sbrannen
Copy link
Member

but the string "null" no longer converts to a null Boolean (wrapper type) after upgrading.

Were you perhaps using the nullValues = "null" feature of @CsvSource as in the following example?

@ParameterizedTest
@CsvSource(nullValues = "null", value = ...)
void myTest(...) {
}

If not, I don't see how "null" would have been converted to a Boolean null.

@sbrannen sbrannen changed the title DefaultArgumentConverter no longer treats "null" as false DefaultArgumentConverter no longer treats null as false Sep 22, 2023
@sbrannen
Copy link
Member

sbrannen commented Sep 22, 2023

In summary, the following test passes against 5.9.x.

	@ParameterizedTest
	@CsvSource(nullValues = "null", textBlock = """
			apple,   True
			banana,  true
			lemon,   false
			kumquat, null
			""")
	void yummyFruit(String fruit, Boolean yummy) {
		switch (fruit) {
			case "apple" -> assertThat(yummy).isTrue();
			case "banana" -> assertThat(yummy).isTrue();
			case "lemon" -> assertThat(yummy).isFalse();
			case "kumquat" -> assertThat(yummy).isNull();
			default -> fail("Unexpected fruit : " + fruit);
		}
	}

Whereas, the following test fails against 5.9.x, since nullValues = "null" has been removed and yummy for kumquat is now false.

	@ParameterizedTest
	@CsvSource(textBlock = """
			apple,   True
			banana,  true
			lemon,   false
			kumquat, null
			""")
	void yummyFruit(String fruit, Boolean yummy) {
		switch (fruit) {
			case "apple" -> assertThat(yummy).isTrue();
			case "banana" -> assertThat(yummy).isTrue();
			case "lemon" -> assertThat(yummy).isFalse();
			case "kumquat" -> assertThat(yummy).isNull();
			default -> fail("Unexpected fruit : " + fruit);
		}
	}

To make the above test pass, you have to change the assertion for kumquat as follows.

	@ParameterizedTest
	@CsvSource(textBlock = """
			apple,   True
			banana,  true
			lemon,   false
			kumquat, null
			""")
	void yummyFruit(String fruit, Boolean yummy) {
		switch (fruit) {
			case "apple" -> assertThat(yummy).isTrue();
			case "banana" -> assertThat(yummy).isTrue();
			case "lemon" -> assertThat(yummy).isFalse();
			case "kumquat" -> assertThat(yummy).isFalse();
			default -> fail("Unexpected fruit : " + fruit);
		}
	}

The latter test passes against 5.9.x but fails against 5.10.x with the originally reported error message Failed to convert String "null" to type java.lang.Boolean.

So the regression is that "null" is no longer converted to a boolean false.

But... that makes sense, because we now only convert "false" (ignoring case) to a boolean false.

@sbrannen sbrannen changed the title DefaultArgumentConverter no longer treats null as false DefaultArgumentConverter no longer converts "null" to false Sep 22, 2023
sbrannen added a commit that referenced this issue Sep 22, 2023
…ed tests

2 tests in this commit currently fail due to changes in 5.10 with the
failure message:

Failed to convert String "null" to type java.lang.Boolean

This will be addressed in a subsequent commit to align with the
expected behavior in 5.10.x.

See #3472
sbrannen added a commit that referenced this issue Sep 22, 2023
This commit updates the tests introduced in the last commit in order to
align with the expected behavior in 5.10.x.

See #3177
See #3472
sbrannen added a commit that referenced this issue Sep 22, 2023
…ed tests

2 tests in this commit currently fail due to changes in 5.10 with the
failure message:

Failed to convert String "null" to type java.lang.Boolean

This will be addressed in a subsequent commit to align with the
expected behavior in 5.10.x.

See #3472
sbrannen added a commit that referenced this issue Sep 22, 2023
This commit updates the tests introduced in the last commit in order to
align with the expected behavior in 5.10.x.

See #3177
See #3472
@sbrannen
Copy link
Member

To observe the actual behavioral changes, consult the following commits.

  • Status quo for 5.9.x: 738b13c
    • ported to 5.10.x and main unchanged: 849ce5e
  • Status quo for 5.10.x and main: ab160b0

The latter commit makes it clear that the only thing that has changed is that we now only convert "false" (ignoring case) to a boolean false.

@JKomoroski
Copy link
Author

This is very helpful. Thank you. I'll update my csv source tests with this in mind. I'll further investigate my other failing tests to see what else could be the problem.

@sbrannen
Copy link
Member

This is very helpful. Thank you.

You're welcome.

I'll update my csv source tests with this in mind. I'll further investigate my other failing tests to see what else could be the problem.

OK. Let us know if you run into any other issues.

@JKomoroski
Copy link
Author

All of my failures were related to @CsvSource changes. The other failures from the upgrade to 5.10 in my work do not have an underlying problem with Junit5. This issue can be closed.

@sbrannen sbrannen removed this from the 5.10.1 milestone Sep 23, 2023
@marcphilipp marcphilipp closed this as not planned Won't fix, can't repro, duplicate, stale Dec 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants