codeconsole opened a new pull request, #16399:
URL: https://github.com/apache/grails-core/pull/16399
Plugins and applications moved off the bean builder DSL to `beanRegistrar()`
(#15934, #15994) and the `beans` DSL (#16019, #16292), but unit tests were left
on `doWithSpring()`. `GrailsUnitTest` had no `beanRegistrar()` hook, and a test
had no way to use the `beans` DSL at all: the implicit convention covers only
plugin descriptors and `Application` classes, and Spring never processes a
Spock specification as a configuration class. Including a plugin through
`getIncludePlugins()` also stopped bringing in all of its beans once they moved
into a `beans` block, because the test harness registers only `org.grails`
auto-configurations, so a third-party plugin's generated `FooAutoConfiguration`
never reached a unit test. `defineBeans(plugin)` cannot fill that gap: a
`beans` block is an auto-configuration, and the context has already refreshed
by then.
This gives tests the same hooks.
- **`beanRegistrar()`** on `GrailsUnitTest`: a `BeanRegistrar` for the
test's context, applied where an application's is at boot, after
`doWithSpring()`, so a registrar bean wins a name conflict with the DSL.
- **`getConfigurationClasses()`**: configuration classes registered ahead of
the framework's auto-configurations, as an application's own configuration is,
so an auto-configuration's `@ConditionalOnMissingBean` backs off from the beans
they declare. By default these are the static nested `@Configuration` classes
of the test and of any test it extends, following the convention Spring's own
test support uses. Adding `@GrailsBeans` to such a class is how a test uses the
`beans` DSL:
```groovy
class ReportServiceSpec extends Specification implements
ServiceUnitTest<ReportService> {
@GrailsBeans
@Configuration
static class Beans {
def beans = {
bean(SomeHelper)
bean('reportCache', ReportCache) { SomeHelper someHelper -> }
}
}
}
```
Overriding it registers the returned classes instead.
- **Included plugins' `beans` blocks.** For each plugin
`getIncludePlugins()` includes, the class its `beans` block compiles to is
registered with the auto-configurations. The name is the one `@GrailsBeans`
gives it by default (`FooGrailsPlugin` → `FooAutoConfiguration`), and a class
is registered only if the build listed it in the auto-configuration imports.
- **`doWithSpring()` on `GrailsUnitTest` is deprecated**, matching `Plugin`
and `GrailsApplicationLifeCycle`.
The unit testing guide now leads with the new hooks and marks `doWithSpring`
deprecated. The upgrade guide and What's New cover the deprecation.
### Separate commit: nested types in the `beans` DSL
Testing this turned up a DSL bug, fixed in its own commit.
`bean(Outer.Helper)` derived its name from `ClassNode#getNameWithoutPackage()`,
the binary `Outer$Helper`, so it registered `outer$Helper` rather than the
documented default, the type's decapitalized simple name `helper`. Nested types
are the usual shape of a test's fixtures. The simple name now comes from the
outer class when the type is compiled alongside it, and from
`Class#getSimpleName()` for a type that is already compiled. No in-tree `beans`
block derives a name from a nested type, so none of their bean names change.
### Compatibility
- A test that already has a static nested `@Configuration` class meant for
something else (an `ApplicationContextRunner`, say) now has it registered in
its own context too. The upgrade guide says to override
`getConfigurationClasses()` to leave it out. No test in this repository is
affected: none pairs a testing trait with a nested `@Configuration` class.
- A plugin that renames its generated class with
`@GrailsBeans(autoConfigurationName = ...)` is not matched through
`getIncludePlugins()`. The unit testing guide says to list that class in
`getConfigurationClasses()`.
- `GrailsApplicationBuilder` gains `beanRegistrar` and
`configurationClasses` properties, and `registerPluginDiscoveryBean` returns
the registered discovery if it is asked twice. The discovery is now created
before the auto-configurations are chosen.
### Validation
```text
./gradlew :grails-testing-support-core:codeStyle :grails-beans-dsl:codeStyle
\
:grails-testing-support-core:test :grails-beans-dsl:test
./gradlew :grails-databinding:test :grails-gsp:test \
:grails-test-examples-beans-dsl:test
:grails-test-examples-beans-dsl-plugin:test \
:grails-test-suite-web:test :grails-test-suite-uber:test
:grails-test-suite-persistence:test --continue
```
- `grails-testing-support-core`: 18 tests, 0 failures. With the production
changes stashed, 8 of the new specs fail; the one that still passes asserts
that a plugin not included contributes nothing. With the test's configuration
classes registered after the auto-configurations instead of before, the
back-off spec fails.
- `grails-beans-dsl`: 420 tests, 0 failures. The new nested-type spec fails
without the fix.
- Regression suites: 1,822 tests, 0 failures, all executed fresh
(databinding 33, GSP 666, test-suite-web 435, -uber 576, -persistence 101,
beans-dsl examples 11).
- Checkstyle and CodeNarc: no violations in either module.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]