ResourceBundleProvider cannot be injected in a JUnit testing context
Greetings,
I am injecting a ResourceBundleProvider into a model as shown below. This works great, but I'm having difficulty writing a JUnit test for this class because I can't find a way to populate the ResourceBundleProvider during test execution. I am certain the problem is related to the Filter annotation because if I remove it, the test will work (but then the field will be null during live execution).
// PeopleAggregationImpl.java
import javax.inject.Inject;
import org.apache.sling.i18n.ResourceBundleProvider;
import org.apache.sling.models.annotations.Filter;
@Model(
adaptables = { Resource.class },
adapters = { PeopleAggregation.class },
resourceType = { PeopleAggregationImpl.RESOURCE_TYPE },
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
public class PeopleAggregationImpl extends BaseComponentImpl implements PeopleAggregation {
@OSGiService
private GeographicLocationService geographicLocationService;
@586265
@10410875("(component.name=org.apache.sling.i18n.impl.JcrResourceBundleProvider)")
private ResourceBundleProvider resourceBundleProvider;
private String geoCountryCodes;
public String getGeoCountryCodes() {
return geoCountryCodes;
}
@PostConstruct
public void init() {
Locale languageLocale = ComponentModelUtil.getLocale(resource);
geoCountryCodes = getGeoCountryCodesJson(languageLocale);
}
private String getGeoCountryCodesJson(Locale locale) {
JsonArray countryCodeArray = new JsonArray();
if (resourceBundleProvider != null) {
final ResourceBundle resourceBundle = resourceBundleProvider.getResourceBundle(locale);
I18n i18n = new I18n(resourceBundle);
Map<String, String> countryMap = geographicLocationService.getGeoLocationCountryMap();
for(Map.Entry<String, String> entry : countryMap.entrySet()) {
JsonObject countryObject = new JsonObject();
countryObject.addProperty("countryCode", entry.getValue().toLowerCase());
countryObject.addProperty("countryName", i18n.get(entry.getKey()));
countryCodeArray.add(countryObject);
}
}
return countryCodeArray.toString();
}
}
I've tried many techniques including creating mock ResourceBundleProviders and mock JcrResourceBundleProviders, but nothing has worked. The example below demonstrates just one of these attempts.
// PeopleAggregationImplTest.java
import org.apache.sling.i18n.ResourceBundleProvider;
import org.apache.sling.i18n.impl.JcrResourceBundleProvider;
import org.junit.Rule;
import io.wcm.testing.mock.aem.junit.AemContext;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import com.tnc.aem.models.PeopleAggregation;
@RunWith(MockitoJUnitRunner.class)
public class PeopleAggregationImplTest {
private static final String RESOURCE_PATH = "/content/page/jcr:content/tab_container/people_aggregation";
private ResourceBundleProvider resourceBundleProvider = Mockito.mock(JcrResourceBundleProvider.class);
@Rule
public final AemContext ctx = new AemContext(ResourceResolverType.JCR_MOCK);
@Before
public void setUp() throws Exception {
ctx.addModelsForClasses(PeopleAggregationImpl.class);
ctx.registerService(ResourceBundleProvider.class, resourceBundleProvider);
}
public void testPeopleAggregation() throws NoSuchFieldException{
Resource resource = ctx.resourceResolver().getResource(RESOURCE_PATH);
PeopleAggregation peopleAggregation = resource.adaptTo(PeopleAggregation.class);
}
Please let me know if you have any ideas how I can populate the ResourceBundleProvider dependency.


