2017-10-11 64 views
0

我想写一个JUnit测试,注入服务依赖关系。Guice注入Ratpack服务器的JUnit测试

protected MainClassApplicationUnderTest aut = new MainClassApplicationUnderTest(App.class) { 
    @Override 
    protected void addImpositions(final ImpositionsSpec impositions) { 
     impositions.add(UserRegistryImposition.of(appRegistry -> { 
      // Allow modifying Injector in tests 
      return appRegistry.join(Guice.registry(injector)); 
     })); 
    } 
}; 

private Injector injector = com.google.inject.Guice.createInjector(new Module()); 

@Before 
public void setup() { 
    injector.injectMembers(this); 
} 

@After 
public void tearDown() { 
    aut.close(); 
} 

,然后用注射服务在我的测试类:

@Inject 
private UserService userService; 

这是工作的罚款,直到我开始添加持久化到我的应用程序HikariModule。现在吉斯注册表创作是一个比较复杂的:

.join(Guice.registry(b -> b 
     .module(HikariModule.class, hikariConfig -> { 
      final String dbUrl = System.getenv("JDBC_DATABASE_URL"); 
      hikariConfig.setJdbcUrl(dbUrl); 
     }) 
     .module(Module.class) 
     .bind(DbMigrator.class) 
    ).apply(r)) 

因为我的注册表现在由多个模块组成,如果我有这取决于DataSource类来从HikariModule吉斯注射试验失败的服务。

我的目标是让编写测试以下列方式:

@Inject // <- not required can be done in @Before method 
private UserService userService; // <- Inject it somehow from Application under test 

@Test 
public void testUser() { 
    final Result<User, String> userResult = userService.create(new User.Registration()); 
    final ReceivedResponse res = aut.getHttpClient().get("https://stackoverflow.com/users/" + user.userId); 
    assertEquals(200, res.getStatusCode()); 
} 

什么是测试注射服务的依存关系的正确方法?我非常喜欢重复使用来自MainClassApplicationUnderTest的guice模块,而不是创建我自己的并覆盖它们。

回答

0

经过相当一段时间的处理与这个问题和Ratpack松懈的帮助后,我设法把这个关闭。

首先,我们需要在本地变量中捕获我们的应用程序注册表。

private Registry appRegistry; 

protected MainClassApplicationUnderTest aut = new MainClassApplicationUnderTest(App.class) { 
    @Override 
    protected void addImpositions(final ImpositionsSpec impositions) { 
     impositions.add(UserRegistryImposition.of(r -> { 
      appRegistry = r; 
      return Registry.empty(); 
     })); 
    } 
}; 

事实证明,有一个漂亮的方法来启动应用程序。所以当注入类时,我们会知道Registry不会为空,我们可以注入类。

protected <T> T inject(final Class<T> classOf) { 
    aut.getAddress(); 
    return appRegistry.get(classOf); 
} 

然后在测试类中,我们可以简单地注入注册表中存在的任何类。

final UserService userService = inject(UserService.class); 
// OR 
final DataSource dataSource = inject(DataSource.class);