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

FieldUtils.readField returns static fields #2000

Closed
henri-tremblay opened this issue Sep 21, 2020 · 9 comments
Closed

FieldUtils.readField returns static fields #2000

henri-tremblay opened this issue Sep 21, 2020 · 9 comments
Assignees
Labels
type: breaking change A change that modifies the behavior of an existing feature
Milestone

Comments

@henri-tremblay
Copy link

Summary

The issue came from hasFieldOrPropertyWithValue. FieldUtils.readField will consider values from static fields to be what we are looking for. I think static fields should be ignored.

This behavior is new. This test used to work in 3.14 and doesn't in 3.17.

Example

public class A {
  public static final String KEY = "KEY"

  Map<String, String> values = new HashMap<>();

  public String getKey() { // Not called because we will look for getKEY and not getKey. That's fine
     return values.get(KEY);
  }
}

A a = new A();
a.values.put(KEY, "x");

assertThat(a).hasFieldOrPropertyWithValue(A.KEY, "x"); // A.KEY is matched instead of the value in the map.
@scordio
Copy link
Member

scordio commented Sep 21, 2020

Hi @henri-tremblay, I would not expect assertThat(a).hasFieldOrPropertyWithValue(A.KEY, "x") to match the value in the map because values is a field of A. The behavior you mentioned can happen if A implements Map, see:
https://github.com/joel-costigliola/assertj-core/blob/3c6bb8a5d4f452c60cf3c8e336a03feba5e9b207/src/main/java/org/assertj/core/util/introspection/PropertyOrFieldSupport.java#L74-L78

Or did I misunderstand your example?

I tried to run the example on 3.14 and 3.17.2, both fail with:

Expecting
  <com.example.A@18bc90ba>
to have a property or a field named <"KEY"> with value
  <"x">
but value was:
  <"KEY">

Ignoring static fields could be a separate topic, but right now I cannot see how the assertion would verify the value of values.get(KEY).

@henri-tremblay
Copy link
Author

A does implement map in my case. But it goes out before that.

Let me get back with a full example. I apologize, I did it a bit too quickly from an actual issue I had in my code.

@scordio
Copy link
Member

scordio commented Sep 22, 2020

I was able to reproduce the case you mentioned, the root cause is probably #1763.

I am not sure we should entirely ignore static fields as this could prevent the verification of non public values.
We currently verify values in the following order:

  1. input name as property
  2. input name as field
  3. input name as map key, if the object is an instance of Map

Maybe it could be reasonable to ignore static fields during 2 and try them only if 3 failed. @joel-costigliola thoughts?

@joel-costigliola
Copy link
Member

I think we should ignore static fields by default, hasFieldOrPropertyWithValue was meant to check instance's fields or properties.
If people want to check static fields we could introduce hasStaticFieldWithValue in class assertions.

@henri-tremblay
Copy link
Author

I agree with @joel-costigliola.

@scordio
Copy link
Member

scordio commented Sep 24, 2020

My only concern is that FieldUtils.readField is a core element and the change of the behavior will affect other features (extracting and recursive comparison configuration, for example).

Or we would need to do a bigger refactoring to make sure only hasFieldOrPropertyWithValue is changed.

@joel-costigliola
Copy link
Member

For recursive comparison, the intent was not to check static fields, for extracting I would argue the same.
It is a breaking change for sure but I feel it's a reasonable one as the initial goals was not to check static fields.
@scordio WDYT?

@scordio
Copy link
Member

scordio commented Sep 24, 2020

I agree, static field verification is really a corner case. Ok, I can drop the bad 👮‍♂️ hat!

@joel-costigliola joel-costigliola added this to the 3.19.0 milestone Nov 30, 2020
@joel-costigliola joel-costigliola self-assigned this Dec 5, 2020
@joel-costigliola joel-costigliola added the type: breaking change A change that modifies the behavior of an existing feature label Dec 5, 2020
@joel-costigliola
Copy link
Member

Fixed in 2f3eeb9.
I also ignored synthetic fields

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: breaking change A change that modifies the behavior of an existing feature
Projects
None yet
Development

No branches or pull requests

3 participants