Thursday, December 24, 2009

Mocking Objects To Unit Test Android OS Applications

First Things First
Testing applications for Android OS can be done in two ways:
  • test on the Android platform using android.test and android.test.mock classes, or
  • testing on the development machine using the regular Java VM and standard Java unit testing and object mocking frameworks.
The good discussion as to pros and cons of each is presented in this article by a Google developer (although not an Android developer). The conclusion was to use the second option, due to valid limitations ofTo the first approach.

Mocking

What are mock objects? They are fake objects that can pretend to the callers to be an object they pretend to be, but are under full control of the test. Full control means two things here:
  • The test can monitor what methods of a mock object are called during the test and what parameters are provided, and
  • The test can dictate what results a mock class should return, without having to actually use, or even implement the class that is mocked.
Why mock objects? Without mocking objects, unit testing is limited to cases where the class under test doesn't use any other classes, or may be just some basic classes. The fuller answer is to why, can be given the following answers. To simplify explaining these answers, let's assume that we want to test class A which uses class B:
  • If some of the class A results depend on class B results. Without using mocking, the test would include the testing of class B. Often, we want to be able to write a test that tests just a single class. Smaller tests can be less brittle, that is they don't break as often with the changes done to the code after the test has been written.
  • If using class B in the test environment is not practical. For example, if the class B is a database, a web service or a GPS module, both of which are tightly coupled to the real world.
  • If we want to test class A before class B is implemented, so it doesn't exists, yet.
  • In general, mocking allows us to test not only an internal code of class A, but also if it uses class B correctly. So, it tests the class collaboration.
For more info on this topic see wikipedia article or this.

What Tools Are Available for Mocking?
The least of tools is quite long. In last couple years, I used probably the following ones:
  • JMock
  • Easy Mock
  • Mockito
  • PowerMock
The reasons I moved from one framework to another are new features (PowerMock can mock even static and final methods) and simpler syntax/tests (esp. Mockito). Also, PowerMock is in a way a conglomerate of Mockito and EasyMock. Although, that means that sometimes, when you use PowerMock you have to use the Mockito, and sometimes the EasyMock like API's. The good part is, that onces you know what mocking is about, using different API's is not that different.

Monday, December 14, 2009

Using JSON RESTfull Web Services in A Flex Application

Choice of JSON Library for Flex
After a few hours of googling, I have decided that the strongest candidate is the corelib library, which for ActionScript 3 is called as3corelib. It's hosted on Google code, although there are multiple references to it on Adobe website. However, none of these references pointed me to any trace of corelib on Adobe website. I wasn't able to figure out why. Leave a comment if you know the story behind.

It seems, that Flash Builder 4 comes with a HTTPService Wizard, which can import a JSON webservice, among other formats.

Limitations of Flash HttpService for RESTfull Webservices
The problem is that because FlashPlayer uses the browser for all networking operations, and Safari browser supports only Post and Get operations, HttpService doesn't support Put, Delete, Headers and Options operations. As a workaround, there is a library hosted on Google Code called RestHttpService, that can be used.

Using Eclipse IDE: Tips, Facts and Tricks

  • If a value gets stuck in Eclipse caches/preferences that doesn't make sense and you can't find a way to update to the new value using Eclipse GUI:
    • Search the workspace/.metadata folder for the obsolete value and correct it, esp. the .settings files. Don't touch binary files, unless you know what you're doing.
    • clean the Eclipse cache by starting exlipse, just once, with the first command line argument set to -clean
    • export preferences, switch to a new workspace and re-import the saved prefs.
    • reinstall Eclipse
    For more info see this great article.
  • The Project Delete doesn't delete any files from the project directory, not even from the .settings folder, unless you check the Delete files... checkbox. Question: is any information lost if I delete a project and then re-import it?
  • How to add a .jar file to classpath without using absolute paths? Follow these steps:

    • Go to Windows > Prefs > Java > Build Path > Claspath variable. Add a new variable pointing to the jar or to a folder, if there are many jars to add.
    • Go to Java Build Path of your project and click Add Variable. If you have specified a var pointing to a single jar, just select it and click OK. If you have created a var pointing to a folder, select it and click Extend. Then, select the jars you want to add (you can add them all in one step). Click OK.
  • How can I move project to another folder? For me this works:


    • Delete the project
    • Move the folder
    • Re-import the project
     

    Tuesday, December 8, 2009

    RESTfull Webservices Using Java with Introduction to JSON

    Introduction
    What are RESTfull or Rest web services and how can they be implemented in with Java? Also what is JSON and how to make a webservice that returns a JSON object?  This is what this blog is about. Specifically, first, about installing and running a sample RESTfull application available from Jersey project.

    What are RESTfull webservices? See this article. Or any other; there are many.

    Approach 1

    This approach uses one of the samples provided by the Jersey project and uses Maven to install the libraries. It's a bit heavy approach, but it works. Approach 2 below also uses Jersey, but is way lighter and simpler.


    Server Side
    I'm using Eclipse IDE with Glassfish Application Server. The steps for this configuration are:
    • Add Jersey and Jersey Documentation and Examples components to Glassfish using its admin console. Note, use GlassFish v3 Prelude version.  When I used GlassFish v3 Promoted Build, the Examples module was not showing in its Update Tool.
    • Restart the GF server.
    • Find the Jersey samples in GF_Home/glassfish/jersey folder.  Go into helloworld-webapp folder. You should see a .pom file there, that is used by maven. From that folder, run "mvn clean package" command. Install maven if needed.
    • Maven installs many files, and for me it ended with an error saying it can't read the glassfish-embedded-all-3.0-Prelude-Embedded-b10.jar file.  I have located this file in the maven repository (Documents and Settings/user/.m2/...) and found that it was broken.  I had to download it manually from internet (search by the file name).
    • Rerun the mvn command. It finished successfully and created a war file in the target directory.
    • Open GF console, and from Web Applications do a deploy. Point to the above war file and click OK. That did it.
    • Point your browser to http://localhost:8080/helloworld-webapp/helloworld. The string "Hello World" appeared.
    Analyzing the Sample
    After I had the sample running, I have exploded and analyzed the contents of the generated war file. The file had a class file implementing the resource plus two more short config files.

    sun-web.xml:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Servlet 2.5//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_2_5-0.dtd">
    <sun-web-app error-url="">
      <context-root>/helloworld-webapp</context-root>
      <class-loader delegate="true"/>
      <jsp-config>
        <property name="keepgenerated" value="true">
          <description>Keep a copy of the generated servlet class' java code.</description>
        </property>
      </jsp-config>
    </sun-web-app> 

    web.xml:
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
        <servlet>
            <servlet-name>Jersey Web Application</servlet-name>
            <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
            <init-param>
                <param-name>com.sun.jersey.config.property.packages</param-name>
                <param-value>com.sun.jersey.samples.helloworld.resources</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>Jersey Web Application</servlet-name>
            <url-pattern>/*</url-pattern>
        </servlet-mapping>
    </web-app> 

    Approach 2
    Approach 1 worked OK, but I wasn't able to apply the sample to deploy an application of my own. And so I searched for a tutorial that uses Eclipse and possibly no Maven. I have run into this mini tutorial which worked great. I was able to drop this application into a Tomcat 6.0 and GlassFish 3 Prelude containers and it worked in both fine.
    Also, this example illustrates how the service can be implemented for different response formats, leaving to the requestor to decide which one to use.

    JSON
     JSON is simply a format, in a way an alternative to XML, that is especially useful for (de-)serializing objects, for example in order to send them over internet. The format is derived from JavaScript native format, but it became language neutral.  Here's a sample:
    {"name":"Alfred Alfredo","age":"47"}
    A nice and concise description of JSON syntax is on JSON website. To have your RESTfull webservice return a JSON object, download and add to the project jettison.jar that Jersey uses to create a JSON object. Now, for the sake of the demonstration, say that the webservice need to return a Person object:

    @XmlRootElement
    public class Person {
     public String name;
     public int age;
     
     public Person() {} // required by JAXB
     
     public Person(String name, int age) {
      this.name = name;
      this.age = age;
     }
    }

    Thanks to the annotations in this class, in order to return a JSON object we just need to define a method:

    @Path("/person")
    public class PersonResource {
      @GET  @Produces("application/json")
      public Person get() {
       return new Person("Alfred Alfredo",47);
      }
    }

    The JSON object as specified above, in the first part of this section will be returned. You can test it using a browser by pointing it to http://localhost:8080/jersey1/rest/person, where jersey1 is the context of my web app, rest is my servlet mapping and person is what I defined with @Path in my RESTful resource class.

    Tuesday, December 1, 2009

    Presenting Business Objects Reports in PDF Format Using Web Services

    Suppose you have a web application, whether of an RIA type or Web 1.0 type, that needs to present a report. One of the attractive options, is to have the report show in the browser as a PDF document. It seems an interesting option, because most users already have Adobe Acrobat Reader installed and are familiar with it. They usually know how to navigate through the document, print it or save it for emailing or just for later use.
    If your organization is also one of the many that use Business Objects (BO) as their standard reporting technology, the solution presented below may be for you.

    Since version XII, the Business Object Enterprise server is bundled and by default installs the web services module which allows to access reports via SOAP web services. Here's the solution:
    • The web application requests a report by calling the special reporting servlet, passing to it the report ID and required parameters.
    • The servlet uses web services to login to BO server and request the report, which then is returned to the client and displayed in a new browser tab or window in Acrobat Reader.
    The example below, shows the solution for the case when the client is a Flex application and the servlet is implemented in Java.

    Reporting Servlet
    The servlet consists of the following modules:
    • login module (login to BO server)
    • report parms module (requests a list of the parameters required by the report and prepares them)
    • report viewer module (configures the request to return the report in PDF format)
    • retrieve and deliver module (requests the report from BO server and sends it on its way back to the client)
    Login Module:
    
      SessionSoap session = new SessionSoapProxy("http://crystalbo:8080/dswsbobje/services/session");
      EnterpriseCredential credents = new EnterpriseCredential();
      credents.setLogin(businObjectsLoginName);
      credents.setPassword(businObjectsLoginPwd);
      SessionInfo si = session.login(credents);
      if( si == null ) { login failed... }
      // Instantiate Report Engine
      ReportEngineSoap rptEngine = new ReportEngineSoapProxy();