In unit test with mockito and Junit 5

with version Spring Boot 2.3.4 @Mock HttpHeaders works

Spring Unable to mock HttpHeaders since Spring Framework 5.3

Spring Unable to mock HttpHeaders since Spring Framework 5.3

but in version 2.4.X this error appears, apparently Mock HttpHeaders is null or empty in this verification

Spring Unable to mock HttpHeaders since Spring Framework 5.3

Spring Unable to mock HttpHeaders since Spring Framework 5.3

with version Spring Boot 2.3.4 this verification was like this and it worked

Spring Unable to mock HttpHeaders since Spring Framework 5.3

please fix it in new versions, thank you very much.

Comment From: mbhave

@ERAGON-JCV Can you provide a small sample that we can run to reproduce this behavior? It can be a zip or a link to a GitHub repository. I don't think there's anything in Spring Boot itself that would cause this behavior but a sample will help understand what's going on.

Comment From: ERAGON-JCV

Hi, in this repository is the sample https://github.com/ERAGON-JCV/issueHttpsHeaders

is with vesion spring boot 2.4.2, with this version unit test does not pass and this behavior appears, but if you change of version to 2.3.4.RELEASE the unit test passes.

thank you.

Comment From: mbhave

Thanks for the sample @ERAGON-JCV. This appears to be happening because of this change in Spring Framework. Previously a temp HttpHeaders was created, which would, in this case, return an empty MultiValueMap for headers.headers. With the change mentioned, headers.headers returns null for the mock.

Let's see what the Spring Framework team thinks.

Comment From: sbrannen

@ERAGON-JCV, why are you mocking HttpHeaders?

Why not simply use a new instance of HttpHeaders?

For example, if you remove the @Mock private HttpHeaders headers; declaration in ClientServiceTest and then add the following line to your init() method ...

ReflectionTestUtils.setField(clientService, "headers", new HttpHeaders());

... then your test passes with a real, legitimate instance of HttpHeaders.

Of course, we discourage the use of @Autowired fields in production classes, since that makes it harder to test components. Introducing constructors or setter methods that accept the HttpHeaders and urlMonetaryFee would alleviate the need to use ReflectionTestUtils for setting those private fields.

Comment From: sbrannen

Team Decision: The Spring Framework team does its best to ensure stability in public APIs across releases; however, that does not apply to internal implementation details. Mocking a concrete type such as HttpHeaders can lead to a mock that relies on the internal implementation (which is not part of the public API), and the behavior of such a mock can therefore be incompatible with changes to internal implementation details across releases. In light of that, I am closing this issue.

https://github.com/spring-projects/spring-framework/issues/26509#issuecomment-776616369 provides a viable solution by using a real instance of HttpHeaders.

Aside from that, having an @Autowired HttpHeaders dependency in a Spring-managed component seems questionable. Typically a new instance of HttpHeaders would be created for each request submitted via the RestTemplate. If a single, preconfigured instance of HttpHeaders is desirable, one would typically create one local to its usage and not define one as a singleton bean in the ApplicationContext. Thus, you may wish to reconsider your use of a shared HttpHeaders bean in your application.