java - 通过拦截器或监听器或预处理器覆盖特定的 guice 绑定(bind)

标签 java dependency-injection binding mocking guice

我想知道 Guice 中是否有一种方法可以在创建绑定(bind)之前通过使用监听器或拦截器来覆盖绑定(bind)。

我的场景是:

我有一个绑定(bind)客户端的模块 A,例如:

public static class ProdModule extends AbstractModule {
        @Override
        protected void configure() {
            bind(Client.class).toInstance(ClientBuilder.newBuilder().build());
        }
    }

这个绑定(bind)需要被模拟。所以我想为测试添加一个新模块来注册一个监听器(或其他东西),这样当 Guice 尝试解析该绑定(bind)时,我可以用我想要的任何绑定(bind)替换它。

我确实知道 Modules.override(...) 但这不能用于我的设置。实例化注入(inject)器的代码本质上隐藏在依赖项中。我无权更改代码以使用模块覆盖,但我可以根据需要添加任意数量的新模块。

我不想替换整个模块,也根本不想更改模块代码。

我一直在尝试一些要么不起作用,要么我不确定如何使用它们的方法:

我尝试使用 ProvisionListener。这“有点”起作用。我可以通过使用反射并更改 Provision 上的结果字段来覆盖特定的提供者。这不适用于实例绑定(bind)。

我尝试使用 ElementVisitorBindingTargetVisitor,但是它们并没有真正为我做任何事情。我可能不太明白这两个访问者的目的是什么,我也没有找到太多关于它的文档或例子。

最佳答案

看起来你在倒着解决这个问题——依赖注入(inject)的存在是为了启用测试,所以如果你在使用 DI 框架的同时努力编写可测试的代码,那么值得退后一步思考在更高层次上找出问题所在,而不是试图使框架按照您认为应该的方式运行。

需要模拟此绑定(bind)。”是一个大危险信号。您几乎不需要绑定(bind)模拟对象,因为模拟对象很脆弱,通常用于单一用途的单元测试,而不是由跨应用程序的 DI 框架提供。

如果您正在编写单元测试,则根本不需要框架 - 只需直接实例化被测类,并传入必要的模拟。多亏了依赖项注入(inject),如果所有依赖项都被模拟出来,您应该能够快速地隔离地对一个类进行单元测试——不需要框架。

如果您正在编写集成或其他更大的测试,因此需要构造一个注入(inject)器并测试整个系统,理想情况下,您应该对无法安全测试的组件进行伪造(而非模拟)实现,并且为此类测试安装的备用模块。例如,您的测试注入(inject)器将安装 FakeCreditCardProcessorModule 而不是 CreditCardProcessorModule,并且提供您尝试测试的绑定(bind)的模块足够松散,无需关心安装了哪个处理器模块.如果由于过度耦合的模块而无法选择 Modules.override() 可用于伪造单个绑定(bind)。

只有在测试模块本身的逻辑时才需要绑定(bind) mock(尽管通常不鼓励在模块中放置值得测试的复杂逻辑)。您应该安装被测模块,以及一个单独的模块,该模块为任何必需的绑定(bind)绑定(bind)模拟。这是唯一一次模拟对 DI 框架真正有意义。

如果上述情况均不适用,请提供有关您尝试测试的内容的更多详细信息。

关于java - 通过拦截器或监听器或预处理器覆盖特定的 guice 绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40551723/

相关文章:

java - 检测传递到 c3p0 连接池的无效凭据

c# - 依赖注入(inject)解析和单元测试

javascript - Aurelia 中的全局应用状态

c# - 我应该如何在 .net core 3.0 中绑定(bind)来自 WPF 的 xaml 事件?

java - 在 Java 中执行协整检验的代码

java.lang.NoSuchFieldError : type When creating a Hive table 错误

java - ArrayList放入j.u.c.ConcurrentHashMap后会安全发布吗?

php - ZF2 弃用 : ServiceManagerAwareInterface

wpf - 直接设置绑定(bind)值

mvvm - 更改ObservableCollection的属性不起作用