Skip to Content

Couple of days ago I decided to take a closer look at the CAF 7.1 (CE). That is because of the time I had during my Christmas holidays and the really huge size of the project I’ll be working for after them. One of the main project needs is a WebDynpro application accessing lots of function modules or BAPIs per RFC and implementing lots of additional logic in java. The CAF, in my opinion, would be the best chose for implementing that.

However I always expect my business logic to be covered by unit tests (I hope I am not alone here 🙂 ). I actually stick with the JUnit framework. (Not just because it is better than others, but because it is well known nearly by each java developer. It is also well supported in all modern java IDEs without any additional installations.)

My additional expectation is to run JUnit tests locally in NetWeaver Developer Studio. I would not like to deploy and run them on the server just because it is a waste of time during the development. On the other hand it is clear that the CAF layer has lots of runtime dependencies within SAP Web AS Java and will not run locally (within IDE). So it is needed to build a bridge to the CAF runtime for the test. Fortunately the CAF exposes  application services as EJBs. That helps to access them outside the server very easily.

To test the approach I created a CAF DC with the simple Application Service composed on a public weather forecast web service:

I would not like to describe how to implement an Application Services like this one referring to blogs and the documentation already available at SDN. One aspect however is important for our implementation. The Remote Interface have to be created for our Application Service. That can easily be done by clicking on it and activating the check box as shown in the screen above. After that CAF will add the @javax.ejb.Remote annotation to the EJB implementation and generate the remote interface:

Now we can start implementing our JUnit test for this service. That can be done in a new Java DC

After that enable JUnit support in the created DC by clicking on “Add/Repair Unit Test Support”

That will add the JUnit library reference to the DC. Unfortunately that is not all we need to run the test. Double click on our DC again and add the references to the following SAP components:

                caf/runtime/ear

                engine.j2ee5.facade

                public.test.facade (should already be there)

                tc/bl/testtech (should already be there)

                tc/bl/exception/lib

                tc/bl/logging/api

additionally you have to add a reference to the ear project created by CAF to be able to call your application services.

That is actually not all you need to do remote invocations. Additionally you need the j2ee client library which you can find in your NWDS installation directory under

ECLIPSE_HOME/plugins/com.sap.engine.clientapis_2.0.0.071030103936/lib/sap.comtcjeclientlibimpl.jar<br />This library have to be referenced by creating a new External Library DC  and exposing it as a public part. Don’t forget to reference the public part with this library in your unittests DC. Alternatively you can add the reference to this external jar as usual via the project properties in the java perspective, but it is not recommended.

Creating the tests</p><p>Now we can start writing our tests<br />1) Start the java perspective and select the unittests DC.<br />2) Click in the Menu on “File->New->JUnit Test Case”<br />!https://weblogs.sdn.sap.com/weblogs/images/251713814/image006.jpg|height=306|alt=|width=277|src=https://weblogs.sdn.sap.com/weblogs/images/251713814/image006.jpg|border=0!</p><p>3) Input the package for the test class and the test class name. The methods setUp() and tearDown() are needed later. You should create them. In the “Class under test” you should be able to browse your bean class. If not, check the reference to the ear project as described above. Click on Next.<br />4) Now you can select the business methods of your Application Service for which the tests have to be created:</p><p>!https://weblogs.sdn.sap.com/weblogs/images/251713814/image007.jpg|height=141|alt=|width=262|src=https://weblogs.sdn.sap.com/weblogs/images/251713814/image007.jpg|border=0!</p><p>Following code is needed to implement the test:</p><p>public class TestWeatherService {</p><p>   private InitialContext ctx;//JNDI context<br />       @Before<br />       public void setUp() throws Exception {<br />             Properties props = new Properties();</p><p>          props.put(Context.INITIAL_CONTEXT_FACTORY, “com.sap.engine.services.jndi.InitialContextFactoryImpl”);</p><p>          props.put(Context.PROVIDER_URL, “P4://localhost:50004”);<br />          props.put(Context.SECURITY_PRINCIPAL, “myusername”);<br />          props.put(Context.SECURITY_CREDENTIALS, “mypassword”);<br />          props.put(Context.URL_PKG_PREFIXES, “com.sap.engine.services”);<br />          this.ctx = new InitialContext(props);<br />   }</p><p> </p><p>   @After<br />   public void tearDown() throws Exception {<br />          if (ctx!=null)<br />              ctx.close();<br />   }</p><p>   @Test<br />   public void testGetCitiesByCountry() throws Exception {</p><p>          Object obj =this.ctx<br />.lookup(“ejb:/interfaceName=com.sap.demo.servicelayer.modeled.appsrv.weatherservice.WeatherServiceServiceRemote”); //1          </p><p>          WeatherServiceServiceRemote weatherServiceServiceRemote = ((WeatherServiceServiceRemote)obj); //2</p><p>          CitiesByCountryResponse citiesByCountry =<br />          weatherServiceServiceRemote.getCitiesByCountry(“Germany”);//3</p><p>          List<String> countries = citiesByCountry.getCountries();<br />          Assert.assertTrue(countries.contains(“Nuernberg”));<br />   }<br />}</p><p>The code will work as follows:</p><p>1) The setUp() method will gather all lookup parameters and create the initial context. That is the place where the added sap client library used. Don’t forget to check the P4 port configured on your Web AS Java.</p><p>2) After the context constructed the test method is invoked by the JUnit framework. In this method the lookup for the EJB is being executed (1).  The returned object is casted to the remote interface itself (2).</p><p>3)The test logic can be implemented invoking the remote methods of the EJB.</p><p>4) The tearDown() will close the context session after the execution of the test method.</p><p>You can start the test as usually, clicking in the context menu of the test class and then selecting “Run as… -> JUnit”. You can also execute all test of the project by clicking the same item on the context menu of the project.</p><p>!https://weblogs.sdn.sap.com/weblogs/images/251713814/image008.jpg|height=225|alt=|width=700|src=https://weblogs.sdn.sap.com/weblogs/images/251713814/image008.jpg|border=0!</body>

To report this post you need to login first.

1 Comment

You must be Logged on to comment or reply to a post.

  1. Dimitri Lubenski Post author
    Hi Artem,

    It is actually not possible to test WD in JUnit because it has lots of runtime dependencies from the WD container and J2EE. There is only a way to ¡§extract¡¨ you business logic to CAF or Java DC and design it to be testable. So your motto will be ¡§Design for Testability”. It is actually not the way of working; it is the way of thinkingƒº.

    Due to the fact, that JUnit is an open source tool, you will find lots of tutorials using Google. The blog is only to explain how to proceed with the testing in CAF and some similar scenarios.

    Regards
    Dimitri

    (0) 

Leave a Reply