Here is a solution that worked.
The key is to override the configureDeployment() method of JerseyTest and create DeploymentContext by passing the Application specific ResourceConfig.class instead of overriding configure() method and returning ResourceConfig instance, so that The test container initializes the guice-bridge correctly.
This is with following versions of Jersey, Guice, and HK2 guice-bridge
<jersey.version>2.15</jersey.version>
<jackson2.version>2.4.4</jackson2.version>
<hk2.guice.bridge.version>2.4.0-b10</hk2.guice.bridge.version>
<guice.version>4.0-beta5</guice.version>
1) My Service class
public interface MyService {
public void hello();
}
2) My Mock Service Impl
public class MyMockServiceImpl implements MyService{
public void hello() {
System.out.println("Hi");
}
}
3) My Resource class with Guice injected Service
@Path("myapp")
public class MyResource {
private final MyService myService;
@Inject
public MyResource(MyService myService) {
this.myService = myService;
}
}
4) My Resource Test class
public class MyResourceTest extends JerseyTestNg.ContainerPerClassTest {
@Override
protected Application configure() {
return null;
}
@Override
protected DeploymentContext configureDeployment() {
return DeploymentContext.builder(MyTestConfig.class).build();
}
// other test and setup/teardown methods
}
5) ResourceConfig class
static class MyTestConfig extends ResourceConfig {
@Inject
public MyTestConfig(ServiceLocator serviceLocator) {
packages("com.myapp.rest");
GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator);
GuiceIntoHK2Bridge guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class);
guiceBridge.bridgeGuiceInjector(Guice.createInjector(new MyTestModule()));
}
}
6) My Guice Test Module class
public class MyTestModule implements Module {
@Override
public void configure(Binder binder) {
binder.bind(MyService.class)
.to(MyMockServiceImpl.class);
}
}