Jukito icon indicating copy to clipboard operation
Jukito copied to clipboard

Jukito & archaius2-guice don't play nicely together

Open petehannam opened this issue 8 years ago • 0 comments

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.

petehannam avatar Jan 20 '17 18:01 petehannam