Skip to content

Jukito & archaius2-guice don't play nicely together #77

@petehannam

Description

@petehannam

Hi,

I've been investigating an issue with archaius2 & Jukito, where a configuration injected into a component that is initialised by Jukito is provided to the wrong test.

The symptom is that if you use a Config in one test, then all subsequent tests won't have their Config updated:

This test will pass:

@RunWith(JukitoRunner.class)
@UseModules(Module.class)
public class HangingReferenceTest {

    public static class Module extends AbstractModule {
        @Override
        protected void configure() {
            install(new ArchaiusModule() {

                @Override
                protected void configureArchaius() {
                    Map<String, String> configurationValues = new HashMap<>();

                    configurationValues.put("value1", "one");

                    bindDefaultConfig().toInstance(MapConfig.from(configurationValues));
                }
            });
        }

    }
    
    @Inject
    Provider<Config> configProvider;

    @Test
    public void testConfig() {
        assertThat(configProvider.get().getString("value1"), is("one"));
    }

}

But this test will fail, and if you look through the values of the Config, it just has "value1":

@RunWith(JukitoRunner.class)
@UseModules(Module.class)
public class HangingReference2Test {

    public static class Module extends AbstractModule {
        @Override
        protected void configure() {
            install(new ArchaiusModule() {

                @Override
                protected void configureArchaius() {
                    Map<String, String> configurationValues = new HashMap<>();

                    configurationValues.put("value2", "two");

                    bindDefaultConfig().toInstance(MapConfig.from(configurationValues));
                }
            });
        }

    }

    @Inject
    Provider<Config> configProvider;

    @Test
    public void testConfig() {
        assertThat(configProvider.get().getString("value2"), is("two"));
    }

}

I've been digging around in Jukito and have tracked it down to this bit of code in JukitoModule:

        // Make sure needed keys from Guice bindings are bound as mock or to instances
        // (but not as test singletons)
        for (Key<?> keyNeeded : keysNeeded) {
            addNeededKey(keysObserved, keysNeeded, keyNeeded, false);
            keysNeedingTransitiveDependencies.add(keyNeeded);
        }

Is there a particular reason that you force bind in concrete instances that Jukito observes? Guice should provide them regardless and if I change the code to the follwing then everything is fine in archaius2 and also in your unit tests:

    // Make sure needed keys from Guice bindings are bound as mock or to instances
    // (but not as test singletons)
    for (Key<?> keyNeeded : keysNeeded) {
      TypeLiteral<?> typeToBind = keyNeeded.getTypeLiteral();
      Class<?> rawType = typeToBind.getRawType();
      if (!keysObserved.contains(keyNeeded) && canBeInjected(typeToBind)
          && !shouldForceMock(rawType) && !isAssistedInjection(keyNeeded)) {
        keysObserved.add(keyNeeded);
      }
      keysNeedingTransitiveDependencies.add(keyNeeded);
    }

Thanks in advance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions