我想运行一个单元测试,其中常量与标准版本略有不同。也就是说,在我的默认模块中,以下是
bindConstant().annotatedWith(Names.named("number of players")).to(4);
但在测试中,我想尝试这一行:
bindConstant().annotatedWith(Names.named("number of players")).to(2);
我喜欢在不复制模块的所有其余部分的情况下实现这一点。我真正想要的是一个“默认”模块,它位于一个更专业的模块“下面”,这样如果发生冲突,专用模块就会获胜(而不是抛出异常,这就是guice的作用)。
从本质上讲,我的问题是:如果没有大量代码重复,任何人如何安排多个模块?
更新:我意识到解决方案实际上是使用工厂,而不是此用例中的常量。不过,我仍然有兴趣了解是否有类似模块的层次结构。
答案 0 :(得分:10)
通常在正确使用Guice时,您根本不需要在测试中使用Guice(特别是单元测试......集成和端到端测试,是)。无论如何:
我不确定我理解你要做什么或问题究竟是什么但是......你意识到在创建Injector
时你可以提供任意数量的Module
s对吧,对吗?这是使用Guice的关键部分。根据需要将模块设置为过程或细粒度。您可以拥有只有一个绑定的NumberOfPlayersModule
,然后有时使用具有不同绑定的不同模块(就像您的测试一样)。您还可以创建一个带有构造函数参数的模块,并根据需要将模块创建为new NumberOfPlayersModule(4)
或new NumberOfPlayersModule(2)
。
还有Guice的另一个功能,它允许您使用来自一个或多个其他模块的绑定覆盖一个或多个模块中的绑定。这是这样的:
// FooModule is your module that contains the "number of players" binding and
// some others
Module override = Modules.override(new FooModule())
.with(new AbstractModule() {
protected void configure() {
bindConstant().annotatedWith(Names.named("number of players")).to(2);
}
});
Injector injector = Guice.createInjector(override);
// The int @Named("number of players") for the injector is 2
正如您所看到的,实际上有很多方法可以轻松地配置应用程序。