Guice - 从覆盖内访问原始值

时间:2014-07-31 11:08:16

标签: java guice

测试中,我想换行一个已由其他模块提供的对象。 基本上是这样的(但工作):

Guice.createInjector(Modules.override(
    // This module lives somewhere else and I rather can't change it
    new AbstractModule() {
        @Override
        protected void configure() {
          bind(Ticker.class).to(TickerImpl.class);
        }

        @Provides @Singleton
        public Tacker getTacker(Ticker ticker) {
          return new Tacker(ticker);
        }
    }).with(new AbstractModule() {
        @Override
        protected void configure() {
        }

        // This doesn't work. oldTicker is an instance of 
        // DelegatingInvocationHandler that references the
        // result of this function causing infinite recursion.
        @Provides @Singleton Ticker getTicker(Ticker oldTicker) {
          return new SpyingTicker(oldTicker);
        }
    })).getInstance(Tacker.class).tack();

有没有办法做到这一点?我找到的唯一解决方案是在覆盖中执行此操作:

        @Provides @Singleton
        public Tacker getTacker(Ticker ticker) {
          return new Tacker(new SpyingTicker(ticker));
        }

这是不理想的,因为它复制了原始模块的逻辑,并没有取代在任何地方注入“Ticker”(仅仅是在创建“Tacker”)

1 个答案:

答案 0 :(得分:0)

因为这是一项测试,所以最好的解决方案是简单地替换其他团队提供的整个模块。这允许您更改您认为合适的绑定。但是,如果只有一个变化,我可以理解为什么你不想这样做。

如果您可以让其他团队进行一些小改动,我可以尝试以下方法:

public class ProductionModule extends AbstractModule {
    protected void configure() {
        // snip
    }

    @Provides @Singleton
    protected MyObject provideMyObject(Dependency dependency) {
        return delegateProvide(dependency);
    }

    // note the lack of annotations
    protected MyObject delegateProvide(Dependency dependency) {
        return new MyObject(dependency);
    }
}

然后,在你的测试中:

public class TestModule extends ProductionModule {
   @Override
   protected MyObject delegateProvide(Dependency dependency) {
       return new MyObjectSpy(super.delegateProvide(dependency));
   }
}
相关问题