Skip to main content

EJB3 unit testing - part one - dependency injection

You might want to use an embeddable container for this - but why really - cause it's really simple. EJB3 session beans are POJO's and should be tested like POJO's.

However there are some issues in order to get EJB3 unit tests working. One of them are dependency injection.

How does dependency injection work? Take a look at this method using reflection:


/**
* @param targetBean - the bean to inject into
* @param annotationClass - the annotation class representing the injection
* @param objectToInject - the object to inject into targetBean
*/

private void inject(Object targetBean, Class annotationClass, Object objectToInject)
{
// Scan all (private and public fields) of the bean class
for(Field fld : targetBean.getClass().getDeclaredFields())
{
// See if the specified annotation is present for the field
if(fld.isAnnotationPresent(annotationClass))
{
// See if the field type is appropriate according to the object that is to be injected
if(fld.getType().isAssignableFrom(objectToInject.getClass()))
{
// Make sure that we can set the value of the field (e.g. if it's private)
fld.setAccessible(true);
try {
// Now set the field with the object to inject
fld.set(targetBean, objectToInject);
Logger.getLogger(getClass().getName()).info("Injected "+objectToInject.getClass().getName()+" into "+targetBean.getClass().getName());
} catch (IllegalArgumentException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}


Now let's see how we can inject the entitymanager and invoke a stateless ejb3 session bean:


// Create session bean instance
MySessionBean mySessionBean = new MySessionBean();
// Inject new entity manager
inject(mySessionBean,PersistenceContext.class,Persistence.createEntityManagerFactory("myTestPU").createEntityManager());
// Invoke session bean method
mySessionBean.hello();

Comments

Uma Lade said…
Thank you so much, your example helped me a lot.

I was using EJB3Guice to inject the objects to a session bean and it doesn't work.

I was struggling how it make it work and found your example. Thanks a ton!!
Thanks for feedback. I will soon follow up with part two then...
Uma Lade said…
HI Peter,

Will be waiting for your part two..

another question regarding EJB3Unit.

My project uses eclipselink for persistence, and we are testing EJBs using EJB3Unit which uses hibernate for persistence.

So, we have some problems testing the beans.

For example: One of our entities have @Converter, to convert boolean to char or viceversa.

Im not able to test this entity, as hibernate throws constraintviolatedexception.
it cannot convert to boolean to char, and the related table has this field as 'char(1)'.

So, could you pls suggest any other alternative to test this kind of differences (between hibernate & persistence).

Thanks & Regards
Uma
I'd prefer testing with the same persistence provider as you use in your application - that is EclipseLink.

My colleague has made EJB3Unit use EclipseLink instead of hibernate - but I don't know the details around this myself.

As for my tests, I haven't used EJB3Unit - but rather implemented those parts of EJB3 needed for my tests (which is mostly only a fraction of a complete EJB3 container).

regards,

Peter

Popular posts from this blog

Angular components not reloading on route change

Spent a long time wondering why route changes caused strange effects on my component, and found out that it was because my component wasn't reloading at all. I had this assumption that when a route parameter changed (e.g. /projects/1 changed to /projects/2 ) the component for the route would be reloaded. But this is not the default behaviour of the Angular router. The default behaviour of the Angular router is to reuse the route if the configuration is the same (and not reload the component). But we can override this by providing a RouteReuseStrategy to our @NgModule: providers: [ { provide: RouteReuseStrategy, useClass: AARouteReuseStrategy } ] The full custom implementation of the RouteReuseStrategy will then be like this (and it's the shouldReuseRoute method that changes the behaviour so that the component is reloaded on route parameter change): export class AARouteReuseStrategy extends RouteReuseStrategy { shouldDetach(route: ActivatedRou...

Using Angular i18n translation strings outside templates

As of today in Angular 6 i18n is only available in the templates. So what if we want to use translated messages programatically and outside templates? I still use the component template html file to declare the message to be translated, but by obtaining the TemplateRef ViewChild in the component typescript file I can get the translated messages from typescript. <ng-template #boardInvitationEmailBody let-organization="organization" let-url="url"> <ng-container i18n>You have been invited to join the board portal for</ng-container> {{organization}}. <ng-container i18n> Please follow the link to: </ng-container> {{url}} </ng-template> So in the typescript code i can now call the createEmailBodyTranlated text method to get the translated text for use outside the template. @ViewChild('boardInvitationEmailBody') boardInvitationEmailBody: TemplateRef ; createEmailBodyTranslatedText(org...

Using GIT for offline web app syncing and storage

Offline web applications, progressive web apps (PWA) using service workers for being available offline also needs a way to sync changes with the server. Mostly we store data in JSON documents, and we could identify changes per line - which is something GIT is excellent at. So how could we make the browser a GIT client? I've been working on this for some months now, and compiled libgit2 to webassembly using emscripten - and it turns out to work very well. Some video demos: Cloning a repository: https://youtu.be/rcBluzpUWE4 Merging of file changes: https://youtu.be/xfGrMwLy_tw The project is here: https://github.com/fintechneo/angular-git-filebrowser