Skip to content

Latest commit

 

History

History
118 lines (93 loc) · 4.53 KB

README.md

File metadata and controls

118 lines (93 loc) · 4.53 KB

di-instantiator

Build Status Coverage Status

Inspired by needle4j which creates an instance of a bean initialized with mocks.

In contrast to needle4j this library is not injecting mock objects but instances of the real objects. For interface types an implementation is looked up from the source and gets injected. As a result you´ll get a completely initialized object graph with real objects. You can even override the automatic implementation lookup and provide specific implementations (or mocks if you like).

The library handles all fields which are annotated with @Inject. This can be configured to handle @EJB fields as well for example.

Example

The application code

Use-case class:

public final class DemoUsecaseImpl implements DemoUsecase {
   
   @Inject
   private DemoDao dao;
   
   @Override
   public DemoEntity loadEntity(int id) {
      return dao.loadEntity(id);
   }
   
   @Override
   public void saveEntity(DemoEntity entity) {
      dao.saveEntity(entity);
   }
}

DAO class:

public final class DemoDaoImpl implements DemoDao {
   
   @PersistenceContext(unitName = "PU")
   private EntityManager entityManager;
   
   @Override
   public DemoEntity loadEntity(int id) {
      return entityManager.find(DemoEntity.class, id);
   }
   
   @Override
   public void saveEntity(DemoEntity entity) {
      entityManager.persist(entity);
   }
}

The test

For demonstration purpose we are saving an entity by calling the use case method saveEntity(). Afterwards it is loaded by its ID. The test uses a real database which also could be a mock. This might not be a real world example but demonstrates an advanced use of the library.

@Test
public void test() {
   // Create factory which sets fields annotated by @Inject and @PersistenceContext
   InjectionObjectFactory factory = new InjectionObjectFactory(Inject.class, PersistenceContext.class);
   
   // Create entity manager for test database and let factory use it
   EntityManager entityManager = Persistence.createEntityManagerFactory("TestPU", null).createEntityManager();
   factory.setImplementationForClassOrInterface(EntityManager.class, entityManager);
   entityManager.getTransaction().begin();
   
   // Obtain fully initialized object from factory, this is what will happen:
   // 1. Instantiate DemoUsecaseImpl
   // 2. Lookup implementation of DemoDao
   // 3. Instantiate DemoDaoImpl 
   // 4. Set provided EntityManager in DemoDaoImpl
   // 5. Set DemoDaoImpl in DemoUsecaseImpl
   DemoUsecaseImpl usecase = factory.getInstance(DemoUsecaseImpl.class);
   
   // Save entity and test the result of a reload
   usecase.saveEntity(new DemoEntity(1, "test name"));
   
   DemoEntity loaded = usecase.loadEntity(1);
   Assert.assertEquals("test name", loaded.getName());
}

FAQ

What happens if two implementations are found for one interface?

If there is more than one implementation found an Exception is thrown. To provide a specific implementation use setImplementingClassForInterface(Class<?> interfaceClass, Class<?> implementationClass) or factory.setImplementationForClassOrInterface(Class<? extends T> classOrInterface, T object).

Which annotations are processed?

By default the factory handles all fields which are annotated with @Inject. This can be changed by passing additional annotations in the constructor: InjectionObjectFactory factory = new InjectionObjectFactory(Inject.class, EJB.class, PersistenceContext.class);

Maven

<dependency>
   <groupId>com.github.kaiwinter</groupId>
   <artifactId>di-instantiator</artifactId>
   <version>1.1.1</version>
</dependency>

License

 Copyright 2015 Kai Winter
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
 
     http://www.apache.org/licenses/LICENSE-2.0
 
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.