1/16/ Jersey Test Framework: TDD for Web Services Brian Westrich McWest Corp. JavaOne 10/4/2011 Slides: Code:
2 Outline Tool survey Jersey Test Framework (JTF) primer Test Driven Design/Development (TDD) with JTF Intermediate Jersey via JTF Q&A / Discussion
3 Web services: What do you use? Remote calls: RMI, EJB 2, EJB 3, Web Services, other Web Services type: SOAP, REST REST implementation: Restlet, Jersey, Other
4 Web Services: What tools do you use? Transfer format: XML, JSON Serialization: JAXB, XStream, JibX, Burlap, text, other
5 What is Jersey? Reference implementation for JAX-RS (RESTful Web Services for Java) Straightforward API Production ready Major version numbers mirror JAX-RS versions Version 1.0 released October 13, 2008 Current version: (Sept 16, 2011) 2.0 will be released with JEE7
6 What is Jersey Test Framework (JTF)? Framework for testing Jersey Web Services Runs as “JUnit” test Automatically starts/stops “test” app server, deploys your services Available since Jersey version 1.4 User guide:
7 Types of Web Service testing TypeDescriptionBenefitsDrawbacks MockedCall service class methods directly from tests FastestDoes not test Jersey etc) JTFUse Jersey Test Framework Faster, Tests Jersey service annotations Does not fully simulate production service use (e.g. character encoding) FunctionalCall live services using tools such as soapUI Represen- tative Slowest, Requires test environment, Tests are laborious to write, Tests are brittle
8 Supported “test” app servers JTF in-memory: FAST, no full web services stack (e.g. character encoding) Standalone app servers: slower, more representative Grizzly JTF HTTP Glassfish External (app server of your choice)
9 Getting started with JTF Maven: Non-Maven: See Jersey user guide section 7 Core “Test” app server
10 Sample web service Time Service Purpose: return current time Data format: milliseconds since 1/1/1970
11 TDD mantra Red: write a failing test Green: make it pass Clean: refactor For more on TDD, including cheatsheet and dojo, see
12 RED
13 GREEN 1) Descend from JerseyTest. 2) Write test code that calls the Jersey service. Notes: client() returns an automatically configured client. Test does not compile since “Time” DTO does not exist. Jersey will automatically call JAXB to unmarshal XML into object.
14 GREEN (cont.) 3) Write XSD that generates dto. Code now compiles, but test fails (fast!) as service does not exist. dto name dto package
15 GREEN (cont.) Stack trace shows how JTF works...
16 GREEN (cont.) 4) Write service class Jersey automatically calls JAXB to marshal object into XML.
17 GREEN (cont.) 5) Declare location of service class. Registers all classes in package that annotation
18 GREEN (cont.) 6) Test passes (in less than a second!).
19 GREEN (review) 1 Note: Automatic JAXB marshalling/unmarshalling inherit from JerseyTest 2. register server resources 3. get client 4. specify path 5. select verb
20 CLEAN Example refactor: Extract path to a constant This example refactor... keeps test in sync with service helps users locate service (Eclipse F3) assumes caller in same classloader as service (e.g. thick client jar, service test code). server client
21 JTF tests as sample clients (executable documentation) Example: get without parameters Path Return type
22 JTF tests as sample clients Example: get with header Providing a sample client is more important as service API complexity increases Header name
23 Other JTF testable Web Service features* Parameters (path, query, post/put form or dto) Verbs (get, post, put, delete) Content types (xml, html, pdf,...) Filters (client) Exception mapping Serialization methods (JAXB, JibX, Castor,...) For sample code, see code.mcwest.com/jersey-example For names of classes of sample code, see slide notes
24 Serialization A key element of web services Jersey integrated with JAXB serialization, can use other serialization methods
25 XStream: Simplified object serialization Convert object to xml Convert xml back to object XStream specific xml
26 Serialization research using JTF Try to use of XStream instead of JAXB Will XStream simplify Jersey WS serialization?
27 XStream: client deserialization Service returns XML Must unmarshall XML manually dto
28 XStream: dto Manually coded XStream data transfer object (dto) (JAXB generates dto from XSD) Xstream leads to added dto maintenance effort
29 Xstream: namespace Manual name space configuration Needed for each return type JAXB uses namespace declared in the XSD XStream leads to duplicate maintenance of namespace info
30 XStream: server side serialization Must manually marshall object into XML
31 Manual coding: JAXB XStream For Jersey WS, XStream requires much more manual coding than JAXB
32 Serialization research using JTF Intended simplification would have added end- to-end complexity JTF eases Web Service architectural decisions
Optional Slides: Start
34 Nested XSDs A more serious concern of using Xstream in web services
35 Nested XSDs Reusable XSD (file = jtf-tdd-nested-namespaced-time.xsd)
36 Nested XSDs Example reuse in another XSD. Generated Java object will contain nested XSD namespace in package import statement.
37 Xstream limitation re: nested XSDs No support for namespaces on nested XSDs Must use chameleon XSDs
38 Chameleon XSD Example (file = jtf-tdd-nested-chameleon-time.xsd) Does not declare a namespace
39 Chameleon XSD reuse “include” (like a macro or ‘C’ include) Chameleon assumes namespace of file it is included into
40 Chameleon XSDs: Problems Type name cannot be qualified by namespace Think “Java class in default package” Leads to unwieldly names Item -> InputBatchItem_v3_2 Generated Java class has no record of origin (package) of chameleon code Name collision potential Two chameleon XSDs with same name can’t be imported into same “parent” XSDs
41 Chameleon XSDs: Problems “Ultimately, namespaces, like packages, are there for a reason, which is to locally group a set of types and set them off as being constituent of a given general idea. If you can't put your types in a namespace, you may need to reconsider your design. If you could put your types in a namespace, but choose not to in the hopes of gaining flexibility, expect interoperability and collision problems sooner or later.” Eben Hewitt (2009) Java SOA Cookbook (O'Reilly and Associates)
42 XStream: no nested namespaces SpringSource's position on XStream for WS Note that XStream is an XML serialization library, not a data binding library. Therefore, it has limited namespace support. As such, it is rather unsuitable for usage within Web services. – ws/site/reference/html/oxm.html ws/site/reference/html/oxm.html Problems easily demonstrated using JTF JTF can help demonstrate rationale for architectural decisions
43 Advanced server resource init Initialize server resources with classes: when don't want to load classes in a package for a specific test (e.g. avoid declaration of duplicate contexts) Initialize server resources with objects: create objects and initialize yourself (e.g. inject mocks) (e.g. use a prepopulated Spring bean as a service resource) For working code, see ResourceRegistrar.class in sample code repository (jersey-example/src/test/java/com/mcwest/jersey/example/resource/ResourceRegistrar.java)
JTF wish list Spring servlet capabilities (e.g. filter registration) Easier setup of custom message body readers/writers (e.g. for specialized content types)
Optional Slides: End
46 Summary Jersey Test Framework enables... TDD of web services: RED – GREEN – CLEAN Executable documentation for Web services Quick learning of Jersey features Sound architectural choices
47 Download Slides and Code Slides Link: Code (Mercurial) Host: Repository: jersey-example
48 Jersey Test Framework: TDD for Web Services Brian Westrich McWest Corp. JavaOne 2011 Slides: Code: