I've managed to find a solution.
Basically instead of relying on injection during the Unit test I've used Mockito and FieldSetter.setField
The only change to the source code would be to ensure the defaultInjectionStrategy was Optional. Not ideal but minimal
First we need to adapt the request to core Teaser.class
Teaser coreTeaser = request.adaptTo(Teaser.class);
Then we adapt the request to our custom teaser
CustomTeaser underTest = request.adaptTo(CustomTeaser.class);
Then we set the field that's not injecting
try {
FieldSetter.setField(underTest, underTest.getClass().getDeclaredField("teaser"), coreTeaser);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
Specific to Teaser I also had to set some SlingBindings so that @ScriptVariables were set when adapting the request to Teaser.class
@BeforeEach
request = context.request();
Component component = mock(Component.class);
Style style = mock(Style.class);
SlingBindings slingBindings = (SlingBindings) request.getAttribute(SlingBindings.class.getName());
slingBindings.put(WCMBindingsConstants.NAME_COMPONENT, component);
slingBindings.put(WCMBindingsConstants.NAME_CURRENT_STYLE, style);
request.setAttribute(SlingBindings.class.getName(), slingBindings);
Following may only be specific to our POM setup but thought I'd add for completeness
I also had to bump aem mock junit5 dependency to
<artifactId>io.wcm.testing.aem-mock.junit5</artifactId>
<version>4.0.0</version>