Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
petehannam opened this issue Jan 20, 2017 · 0 comments
Open

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

petehannam opened this issue Jan 20, 2017 · 0 comments

Comments

@petehannam
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant