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

Delay in autoconfiguration of TestBinder #2893

Closed
kutmk opened this issue Jan 28, 2024 · 6 comments
Closed

Delay in autoconfiguration of TestBinder #2893

kutmk opened this issue Jan 28, 2024 · 6 comments

Comments

@kutmk
Copy link
Contributor

kutmk commented Jan 28, 2024

With the update in #2566, it is no longer necessary to import TestChannelBinderConfiguration to use TestBinder.

However, if no message handler is registered (i.e., not defining Supplier/Consumer/Function), it seems that the autoconfiguration of TestChannelBinderConfiguration is delayed. In this case, the injection of OutputDestination fails. Therefore, it is still necessary to import it.

@SpringBootTest
public class AppTest {
  @Autowired
  private OutputDestination outputDestination; // Injection failure

Log excerpt

[ERROR] Errors:
[ERROR]   AppTest.test » UnsatisfiedDependency Error creating bean with name 'com.example.AppTest': Unsatisfied dependency expressed through field 'outputDestination': No qualifying bean of type 'org.springframework.cloud.stream.binder.test.OutputDestination' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Is this the intended behavior? Is it not possible to completely eliminate the import?

Demo and workaround

Demo and workaround: This demo intends to test an application that uses Test Binder, StreamBridge, and OutputDestination without registering a message handler.

Environment

  • Java 17
  • Spring Boot 3.1.1
  • Spring Cloud 2022.0.3
  • Spring Cloud Stream 4.0.3

Cause

The TestChannelBinderConfiguration is autoconfigured when DefaultBinderFactory#initializeBinderContextSimple is executed.

If a message handler is registered, this method is called before the injection of the test class's member variables due to OutputBindingLifecycle or InputBindingLifecycle.

However, if a message handler is not registered, this method is not called until during the application’s execution when a Binder is needed (such as during the execution of StreamBridge#send). As a result, the Bean is not created until then, and the injection fails.

@sobychacko
Copy link
Contributor

@kutmk Your two workarounds are reasonable solutions when using StreamBridge. What is preventing you from going with those options? Ideally, you like to autoconfigure, but there are scenarios in which auto config may not work as in your case when using StreamBridge. A 3rd option is to use a fully self-contained test as many of these tests do. We are open to suggestions if there is a valid use case to address this.

@sobychacko
Copy link
Contributor

@kutmk, do you have any updates on the suggestions above? Since there are ways to address this, we are leaning towards leaving things as they are. Please let us know.

@kutmk
Copy link
Contributor Author

kutmk commented Feb 13, 2024

@sobychacko
Sorry for the late reply. Thank you for suggesting the 3rd option.

Currently, the necessity for import is inconsistent and the conditions are complex. I believe this could lead to confusion for users.
Therefore, if possible, I propose enabling the AutoConfiguration of the TestChannelBinderConfiguration class to ensure that the Bean is always created.

Implementation of the proposal

@sobychacko
Copy link
Contributor

Ok, that sounds good. Why don't you send that as a PR, and we will evaluate for any side effects?

@kutmk
Copy link
Contributor Author

kutmk commented Feb 13, 2024

Of course, I will send a PR.

@sobychacko
Copy link
Contributor

This has been addressed via #2900.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants