使用 Guice 模拟并拥有用于测试目的的真实对象

Mock and having real object for testing purposes using Guice

如何在 Guice 测试模块中创建一个对象,该对象在一个测试中用作模拟,但在另一个测试中需要是真实对象。

例如。 假设我有一个名为 ConfigService 的 class。这是使用构造函数注入注入到另一个名为 UserService 的 class 中。在测试期间,我使用了一个 TestModule,它有各种 classes 及其模拟。

TestModule.java:

public class TestModule extends AbstractModule{
    @Override
    public void configure() {
            ConfigService configService = Mockito.mock(ConfigService.class);
            bind(ConfigService.class).toInstance(configService);

            UserService userService = new UserService(configService);

            bind(UserService.class).toInstance(userService);

    }
}

在 UserServiceTest 中,我创建了一个注入器并使用了这个 TestModule 中的实例。

Injector injector = Guice.createInjector(new TestModule());
userService = injector.getInstance(UserService.class);
configService = injector.getInstance(ConfigService.class);

这个很好用,我现在遇到问题的地方就是需要测试的时候ConfigService.class。

如果我想为 ConfigServiceTest 使用相同的 TestModule,我现在如何将我之前创建的 ConfigService 的模拟对象更改为用于测试的实际对象。反之亦然也是一个问题 - >即。如果我有一个真实的 ConfigService 对象,我该如何存根和模拟 UserService.class.

中的响应

有没有办法实现这个,或者我应该为模拟和真实对象创建单独的测试模块?还是我以错误的方式进行整个过程?

您可以使用 spy 方法做到这一点。

ConfigService realConfigService = new ConfigService();
ConfigService configService = Mockito.spy(realConfigService);
bind(ConfigService.class).toInstance(configService);

间谍所做的是,只要您提供存根,它就会表现得好像对象被模拟了一样。否则会调用对象的真实方法。

请查看此答案以了解更多信息 in-depth theory