我想知道在Guice中是否有一种方法可以通过使用侦听器或拦截器在绑定创建之前覆盖它。
我的场景是:
我有一个绑定客户端的模块a,例如:public static class ProdModule extends AbstractModule {
@Override
protected void configure() {
bind(Client.class).toInstance(ClientBuilder.newBuilder().build());
}
}
这个绑定需要模拟。因此,我希望为测试添加一个新模块,该模块注册一个侦听器(或其他东西),以便当Guice试图解析该绑定时,我可以用我想要的任何绑定替换它。
我确实知道Modules.override(...)
,但是这不能与我的设置一起使用。实际上,实例化注入器的代码隐藏在一个依赖项中。我无法更改代码以使用模块覆盖,但是我可以添加尽可能多的新模块,因为我想要。
我不想替换整个模块,也不想改变模块的代码。
我一直在尝试一些事情,要么不工作,要么我不确定如何使用它们:
我尝试使用ProvisionListener
。这"多少"起作用了。我可以通过使用反射和更改Provision上的结果字段来覆盖特定的提供程序。这对实例绑定不起作用。
我尝试使用ElementVisitor
和BindingTargetVisitor
,然而他们并没有真正为我做任何事情。我可能不太明白这两个访问者的目的是什么,我也没有找到太多的文档或例子。
看起来你是在反着解决这个问题——依赖注入是为了启用测试而存在的,所以如果你在使用DI框架的同时还在努力编写可测试的代码,那么就值得后退一步,在更高的层次上找出问题所在,而不是试图使框架按照你认为它应该的方式运行。
"这个绑定需要模拟。"是一个很大的危险信号。您几乎不需要绑定mock对象,因为mock很脆弱,通常用于单一目的的单元测试,而不是由跨应用程序的DI框架提供。
如果您正在编写单元测试,则根本不需要框架—只需直接实例化所测试的类,并传入必要的mock。多亏了依赖注入,如果一个类的所有依赖都被模拟出来了,你就可以在隔离状态下快速地对它进行单元测试——不需要框架。
如果你正在编写一个集成或其他更大的测试,因此需要构造一个注入器并测试整个系统,理想情况下,你应该有不能安全测试的组件的假(而不是模拟)实现,以及为这些测试安装替代模块。例如,您的测试注入器将安装FakeCreditCardProcessorModule
而不是CreditCardProcessorModule
,并且提供您试图测试的绑定的模块是松散耦合的,不关心安装了哪个处理器模块。如果这不是一个选项,由于过度耦合的模块Modules.override()
可以用来伪造单独的绑定。
只有在测试模块的逻辑本身时才需要绑定mock(尽管通常不鼓励在模块中放置值得测试的复杂逻辑)。您应该只安装要测试的模块,以及为任何所需的绑定绑定模拟的单独模块。这是mock在DI框架中真正有意义的唯一时候。
如果以上场景都不适用,请提供更多关于您要测试的内容的详细信息