在测试中,我想换行一个已由其他模块提供的对象。 基本上是这样的(但工作):
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”)
答案 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));
}
}