我的类中有一个名为MainModule的模块,它有各种绑定,其中一个绑定是到我的自定义服务接口HttpClientPool的绑定
public class MainModule extends AbstractVertxModule{
binder.bind(HttpClientPool.class).to(HttpClientPoolImpl.class).in(Singleton.class);
// other bindings
}
@Provides @Singleton
public TokenClient tokenClient(HttpClientPool clientPool){
return new TokenClient(clientPool);
}
该模块也是一个名为tokenClient的对象的提供者,如上所示。
tokenClient被注入到不同类的其他位置,并且在此对象上调用了一些方法。
在我的单元测试中,我打算使用Mockito来获得一个模拟的tokenClient对象。这意味着,我希望MainModule提供一个模拟的对象,而不是一个真正的对象。我尝试使用一个如下所示的testMainModule:
public class testMainModile implements Module{
private TokenClient tokenClient;
public TokenModule(TokenClient client) {
this.tokenClient= client;
}
@Override
public void configure(Binder binder) {
binder.bind(TokenClient.class).toInstance(tokenClient);
}
}
下面是我的单元测试的一段摘录:
@Mock
private TokenClient tokenClient;
// Stuff between
Injector messagingInjector = Guice.createInjector(new TestMainModule(tokenClient));
mainModule = messagingInjector.getInstance(MainModule.class);
不知怎么的,我得到的只是mainModule对象中的一个真实对象。我是否遗漏了什么?
2条答案
按热度按时间b91juud31#
我假设你有一个提供一些功能的类,这就是你要进行单元测试的类,它需要你注入一个tokenClient才能正常工作,所以你面临的问题是:当我测试被测试的类时,它是如何被注入一个模拟的tockenClient的。
有几种可能性......可能最简单的一种是严格地只使用构造函数注入,通过“new”创建被测类的示例,然后将单独创建的模拟示例交给它们。
如果你想坚持使用guice,可以使用override Bindings and Providers,甚至提供完全隔离的测试模块。
我更喜欢使用needle4j框架(我是一个贡献者,所以我有偏见),一个依赖注入模拟器,默认情况下注入模拟,除非配置为其他方式。如果使用正确(坚持一个类单元,不要试图设置集成级测试),这可能是最快和最简单的方式来测试依赖于注入示例的类。
weylhg0b2#
如果你 * 需要 * 覆盖绑定(例如,如果你不能修改
MainModule
),下面是一个完整的工作示例:备注:
TestMainModule
工作原理:
BoundFieldModule.of(this)
使用测试类中所有用@Bind
注解的字段动态创建一个测试模块。由于tokenClient
也是一个mock示例,因此模块中的绑定将包含mock。Modules.override
将BoundFieldModule
覆盖在MainModule
上。具体地,TokenClient
,因为它优先于BoundFieldModule
中的绑定;和HttpClientPool
,因为这仅在MainModule
中有界。我不确定获取
testMainModule
示例的意义是什么。如果我们想从测试模块中获取HttpClientPool
的示例,我们可以这样做:在这种情况下,注入器使用被重写的模块将
HttpClientPoolImpl
的示例注入到httpClientPool
字段中。