How to inject dependency into JerseyTest? - java

I want to inject MyService directly into my JerseyTest using CDI. Is it possible? MyService is succcefull injected into MyResource but I get NullPointerException when I try to access it from MyJerseyTest.
public class MyResourceTest extends JerseyTest {
#Inject
MyService myService;
private Weld weld;
#Override
protected Application configure() {
Properties props = System.getProperties();
props.setProperty("org.jboss.weld.se.archive.isolation", "false");
weld = new Weld();
weld.initialize();
return new ResourceConfig(MyResource.class);
}
#Override
public void tearDown() throws Exception {
weld.shutdown();
super.tearDown();
}
#Test
public void testGetPersonsCount() {
myService.doSomething(); // NullPointerException here
// ...
}
}

I think you need to provide an instance of org.junit.runner.Runner where you will do the weld initialization. This runner should also be responsible for providing an instance of your Test class with necessary dependencies injected. An example is shown below
public class WeldJUnit4Runner extends BlockJUnit4ClassRunner {
private final Class<?> clazz;
private final Weld weld;
private final WeldContainer container;
public WeldJUnit4Runner(final Class<Object> clazz) throws InitializationError {
super(clazz);
this.clazz = clazz;
// Do weld initialization here. You should remove your weld initialization code from your Test class.
this.weld = new Weld();
this.container = weld.initialize();
}
#Override
protected Object createTest() throws Exception {
return container.instance().select(clazz).get();
}
}
And your Test class should be annotated with #RunWith(WeldJUnit4Runner.class) as shown below.
#RunWith(WeldJUnit4Runner.class)
public class MyResourceTest extends JerseyTest {
#Inject
MyService myService;
// Test Methods follow
}

Related

How to get beans in a hibernate identifier generator?

My application use the Spring and hibernate.
Gotta get the MyService bean in the IdentifierGenerator.
Example:
public class MyGenerator implements org.hibernate.id.IdentifierGenerator, org.hibernate.id.Configurable {
#Autowired // doesn't work :(
private MyService myService;
#Override
public void configure(Type type, Properties properties, ServiceRegistry serviceRegistry) throws MappingException {
}
#Override
public Serializable generate(SessionImplementor sessionImplementor, Object obj) {
...
If you really, really have to do it you can define ApplicationContextHolder utility class and use it to store the Spring context:
#Component
public class ApplicationContextHolder implements ApplicationContextAware {
private static ApplicationContext applicationContext;
#Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
synchronized (this) {
if (ApplicationContextHolder.applicationContext == null) {
ApplicationContextHolder.applicationContext = applicationContext;
}
}
}
public static <T> T getBean(Class<T> clazz) {
return applicationContext.getBean(clazz);
}
public static <T> T getBean(String qualifier, Class<T> clazz) {
return applicationContext.getBean(qualifier, clazz);
}
Afterwards use the static method to obtain MyService bean:
public class MyGenerator implements IdentifierGenerator, Configurable {
#Override
public void configure(Type type, Properties properties, ServiceRegistry serviceRegistry) throws MappingException {
MyService service = ApplicationContextHolder.getBean(MyService.class);
}
}
This goes against the principle of dependency injection, but sometimes there is not better way if some objects are not managed by Spring.

Jukito Provider mock returns null

I am having some issues with a jukito unit test. I can't seem to mock Provider. Examples:.
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
#Singleton
public class ServiceClass1 {
#Inject
Provider<ConnectionClass> provider;
public void method1() {
Object o = provider.get().getO(); //during mainTest, provider is null and I get Nullpointer
}
}
#Singleton
public class ConnectionClass {
public Object getO() {
//this is not relevant
}
}
public class ConfigurationModule extends AbstractModule {
bind(ServiceClass1.class).in(Singleton.class);
bind(ConnectionClass.class).in(Singleton.class);
}
#RunWith(JukitoRunner.class)
public class ServiceClass1Test {
#InjectMocks
ServiceClass1 service;
#Mock
Provider<ConnectionClass> connectionClassProvider;
#Mock
ConnectionClass connectionClass;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
when(connectionClassProvider.get()).thenReturn(connectionClass);
}
#Test
public void mainTest() {
service.method1();
}
}
I expect to get a mocked connection class, but instead provider returns null. I tried binding connectionClass to TestSingleton, but that does not help. Inside test class:
public static class Module extends JukitoModule {
#Override
protected void configureTest() {
bindMock(ConnectionClass.class).in(TestSingleton.class);
}
}
If anyone has some suggestions for me, I would greatly appreciate it.
Using constructor injection instead of field injection:
#Singleton
public class ServiceClass1 {
Provider<ConnectionClass> provider;
#Inject
public ServiceClass1(Provider<ConnectionClass> provider) {
this.provider = provider;
}
}
and dropping InjectMocks:
#Mock
Provider<ConnectionClass> provider;
ServiceClass1 serviceClass1;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
serviceClass1 = new ServiceClass1(provider);
}
makes everything work. Can InjectMocks be the cause of this? Anyway, I guess this will do for now.

Test class which depends on Guice Provider<T>

How to test a class which depends on Provider<>?
Please see the code below.
class ToTest {
#Inject
Provider<Processor> processorProvider;
public buildData() {
processorProvider.get().process();
}
class ProcessorProviderImpl implements Provider<Processor> {
#Inject
private Handler someHandler;
public Processor get() {
return new MyProcessor(somehandler)
}
}
public static class TestModule extends JukitoModule {
#Override
protected void configureTest() {
bind(Processor.class).toProvider(
ProcessorInstanceProviderImpl.class);
bindMock(SubHandler.class).in(TestSingleton.class);
}
}
class Handler {
#Inject
private SubHandler subHandler; // this is singleton instance
}
}
So when I mock subHandler it doesn't work and when I run unit test I am getting a NullPointerException where subHandler.handle() is getting called.
You can use Providers.of() to initialize processorProvider with a provider of your collaborator instance.
https://google.github.io/guice/api-docs/latest/javadoc/index.html?com/google/inject/util/Providers.html
test = new ToTest();
test.processorProvider = Providers.of(processorMock);

Jersey 2 inject dependencies into unit test

I have a controller like this
#Path("/")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public class AccountController implements CRUDController<Long, Account> {
private AccountDao accountDao;
private AccountService accountService;
#Inject
public AccountController(AccountDao accountDao, AccountService accountService) {
this.accountDao = accountDao;
this.accountService = accountService;
}
...
I'm injecting AccountDao and AccountService using
ResourceConfig config = new ResourceConfig()
.packages("controller", "exception")
.register(new MyDIBinder());
Where MyDIBinder is contains all the bindings (e.g
AccountDaoImpl accountDaoImpl = new AccountDaoImpl();
bind(accountDaoImpl).to(AccountDao.class);
)
Now I want to write a unit test for this controller, is it possible to inject the whole AccountController instance with all of it's transitive dependencies into the test?
Something like
#Inject
AccountController accountController;
You can use the main IoC container, and just explicitly inject the test class. Jersey uses HK2 as its DI framework, and its IoC container is the ServiceLocator, which has a method inject(anyObject) that can inject any objects with dependencies that are in its registry.
For example you could do something like
public class InjectionTest {
#Inject
private TestController controller;
#Before
public void setUp() {
final Binder b = new AbstractBinder() {
#Override
public void configure() {
bindAsContract(TestController.class);
}
};
final ServiceLocator locator = ServiceLocatorUtilities.bind(new TestBinder(), b);
locator.inject(this);
}
#Test
public void doTest() {
assertNotNull(controller);
String response = controller.get();
assertEquals("Hello Tests", response);
}
}
The ServiceLocatorUtilities class is a helper class that allows us to easily create the ServiceLocator, and then we just call inject(this) to inject the InjectionTest.
If it seems repetitive to do this for all your controller tests, you may want to create an abstract base test class. Maybe something like
public abstract class AbstractControllerTest {
protected ServiceLocator locator;
private final Class<?> controllerClass;
protected AbstractControllerTest(Class<?> controllerClass) {
this.controllerClass = controllerClass;
}
#Before
public void setUp() {
final AbstractBinder binder = new AbstractBinder() {
#Override
public void configure() {
bindAsContract(controllerClass);
}
};
locator = ServiceLocatorUtilities.bind(new TestBinder(), binder);
locator.inject(this);
}
#After
public void tearDown() {
if (locator != null) {
locator.shutdown();
}
}
}
Then in your concrete class
public class TestControllerTest extends AbstractControllerTest {
public TestControllerTest() {
super(TestController.class);
}
#Inject
private TestController controller;
#Test
public void doTest() {
assertNotNull(controller);
assertEquals("Hello Tests", controller.get());
}
}
If you spent some more time, I'm sure you could come up with a better abstract test class design. It was the first thing that came to mind for me.
Note: For anything request scoped, you mayb need to just mock it. When running the unit tests, there is no request context, so the test will fail.
See Also:
Using Jersey's Dependency Injection in a Standalone application
HK2 documentation
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.utilities.ServiceLocatorUtilities;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
#BeforeClass
public static void doTest() {
ServiceLocator serviceLocator = ServiceLocatorUtilities.bind(new AbstractBinder() {
#Override
protected void configure() {
bindAsContract(YourClass1.class);
bindAsContract(YourClass2.class);
bindAsContract(YourClass3.class);
}
});
YourClass1 yourClass1 = serviceLocator.getService(YourClass1.class);
...

Guice: binding non-immediate dependencies

Here are my classes:
public interface MyService {
// ...
}
public class MyServiceImpl implements MyService {
private MyCommand myCommand;
}
public interface MyCommand {
// ...
}
public class MyCommandImpl implements MyCommand {
private MyDAO myDAO;
}
public interface MyDAO {
// ...
}
public class MyDAOImpl implements MyDAO {
// ...
}
public class MyModule extends AbstractModule {
#Override
protected void configure() {
bind(MyService.class).to(MyServiceImpl.class)
}
}
public class MyDriver {
#Inject
private MyService myService;
public static void main(String[] args) {
MyModule module = new MyModule();
Injector injector = Guice.createInjector(module);
MyDriver myDriver = injector.getInstance(MyDriver.class);
// Should have been injected with a MyServiceImpl,
// Which should have been injected with a MyCommandImpl,
// Which should have been injected with a MyDAOImpl.
myDriver.getMyService().doSomething();
}
}
So this takes care of injecting requests for MyServices with instances of MyServiceImpl. But I can't figure out how to tell Guice to configure MyServiceImpls with MyCommandImpl, and how to bind MyCommandImpls with MyDAOImpls.
The other bindings and injections you need should be set up just like the first one. Use #Inject wherever the instance is needed, and bind the interface to an impl in your module. I've added 4 lines below (annotated 2 injection sites and defined 2 more bindings):
public interface MyService {
// ...
}
public class MyServiceImpl implements MyService {
#Inject
private MyCommand myCommand;
}
public interface MyCommand {
// ...
}
public class MyCommandImpl implements MyCommand {
#Inject
private MyDAO myDAO;
}
public interface MyDAO {
// ...
}
public class MyDAOImpl implements MyDAO {
// ...
}
public class MyModule extends AbstractModule {
#Override
protected void configure() {
bind(MyService.class).to(MyServiceImpl.class);
bind(MyCommand.class).to(MyCommandImpl.class);
bind(MyDAO.class).to(MyDAOImpl.class);
}
}
public class MyDriver {
#Inject
private MyService myService;
public static void main(String[] args) {
MyModule module = new MyModule();
Injector injector = Guice.createInjector(module);
MyDriver myDriver = injector.getInstance(MyDriver.class);
// Should have been injected with a MyServiceImpl,
// Which should have been injected with a MyCommandImpl,
// Which should have been injected with a MyDAOImpl.
myDriver.getMyService().doSomething();
}
}

Categories