My JSF Books/Videos My JSF Tutorials OmniFaces/JSF PPTs
JSF 2.3 Tutorial
JSF Caching Tutorial
JSF Navigation Tutorial
JSF Scopes Tutorial
JSF Page Author Beginner's Guide
OmniFaces 2.3 Tutorial Examples
OmniFaces 2.2 Tutorial Examples
JSF Events Tutorial
OmniFaces Callbacks Usages
JSF State Tutorial
JSF and Design Patterns
JSF 2.3 New Features (2.3-m04)
Introduction to OmniFaces
25+ Reasons to use OmniFaces in JSF
OmniFaces Validators
OmniFaces Converters
JSF Design Patterns
Mastering OmniFaces
Reusable and less-verbose JSF code

My JSF Resources ...

Java EE Guardian
Member of JCG Program
Member MVB DZone
Blog curated on ZEEF
OmniFaces is an utility library for JSF, including PrimeFaces, RichFaces, ICEfaces ...

[OmniFaces Utilities] - Find the right JSF OmniFaces 2 utilities methods/functions

Search on blog

Petition by Java EE Guardians

Twitter

sâmbătă, 18 iunie 2016

CDI-JSF: Use a CDI alternative as a mock implementation for a stateless session bean

A great feature of CDI (supported by Java EE starting with version 6) consist in alternatives. Basically, we want to specify an alternative for an injected object. Let's have a simple scenario commonly followed in JSF applications that uses stateless session beans to interact with a database. Supposing that we write the business logic part to query the database. We can start with an interface as:

public interface IFooService {
 List getAllFoo();
}

Further, we can write a stateless session bean that implements this interface and take usage of JPA capabilities to query the database. Well the things didn't go too far for this part because the database is not ready and all we can provide is a skeleton like below:

@Stateless
public class FooService implements IFooService {
   
 @PersistenceContext(unitName = "fooPU")
 private EntityManager em;

 @Override
 public List getAllFoo() {
  // perform the query
  ...
  return new ArrayList();
 }
}

Finally, we inject the stateless session bean in a CDI managed bean as below:

Named
@RequestScoped
public class FooBean {

 private static final Logger LOG = Logger.getLogger(FooBean.class.getName());

 @Inject
 private IFooService fooService;

 public void loadAllFoo() {
  List allfoo = fooService.getAllFoo();
  LOG.log(Level.INFO, "allfoo:{0}", allfoo);
 }
}

Now, let's suppose that we want to run/test this method, but we have an issue. The data that we expect from the database will not be available, so we think to mock this service and provide a set of dummy data as below:

@Stateless
public class FooServiceMock implements IFooService {

 @Override
 public List getAllFoo() {
  return Arrays.asList("foo 1", "foo 2", "foo 3");
 }
}

But, if we test the code now, we will obtain an error of type ambiguous dependencies. In order to fix this error, we simply annotated our mock with @Alternative annotation:

@Alternative
@Stateless
public class FooServiceMock implements IFooService {

 @Override
 public List getAllFoo() {
  return Arrays.asList("foo 1", "foo 2", "foo 3");
 }
}

If we run now, there will be no errors, but the application will not use the mock. This is happening because our alternative is not activated. We must accomplish this in the beans.xml, as below:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       bean-discovery-mode="all">
   
 <alternatives>
  <class>beans.FooServiceMock</class>
 </alternatives>
</beans>

Done! Now the FooBean will use the FooServiceMock instead of FooService. When the database will be ready/queryable we will simply deactivate the alternative.

Via CDI-Unit we can write a quick test that also uses our mock:

@RunWith(CdiRunner.class)
@ActivatedAlternatives(FooServiceMock.class)
public class FooBeanTest {
   
 @Inject
 FooBean fooBean;

 @Test
 @InRequestScope
 public void testStart() {
  fooBean.loadAllFoo();
 }   
}

The complete example is available here.

Niciun comentariu :

Trimiteți un comentariu

JSF BOOKS COLLECTION

Postări populare

Follow by Email

Visitors Starting 4 September 2015

Locations of Site Visitors