users@jersey.java.net

Re: [Jersey] Here is what I want to do (TDD testing with Spring)

From: Imran M Yousuf <imran_at_smartitengineering.com>
Date: Wed, 25 Mar 2009 11:42:10 +0600

On Tue, Mar 24, 2009 at 7:58 PM, Mats Henricson <Mats.Henricson_at_paf.com> wrote:
> (Sorry for this Outlook enforced reply - I'm stuck in corporate standards).
>
> My objection to this is that I can't see what a web.xml has to do with my
> JUnit tests?
>
> If you work bottom up TDD you deploy in a web container AFTER you know
> your REST stuff has been tested, as seems to be possible with Grizzly.
>
> No?
>

Yes, but I *MAY* have a web.xml for JUnit testing only and it has
minimal configuration just to get the REST stuff to fire up and it
will not be shipped in the REST module, REST Web module will have its
own web.xml. Another point to adding a web.xml to JUnit test is, IMHO,
I would also like my web.xml to be part of the test just to ensure
that it works as expected as well. Also one could take the approach
mentioned by Paul Sandoz as well. IMO, it depends on the approach you
take.

Best regards,

- Imran

> Mats
> ________________________________________
> From: Imran M Yousuf [imran_at_smartitengineering.com]
> Sent: Tuesday, March 24, 2009 12:09
> To: users_at_jersey.dev.java.net
> Subject: Re: [Jersey] Here is what I want to do (TDD testing with Spring)
>
> Sorry I am in a run, just wanted to add that, can you just add the
> following code in your Spring's app context -
>
> <context:component-scan
> base-package="com.smartitengineering.bookstore.ws.server"/>
>
> Please change the package name appropriately.
>
> And your web.xml should have the following -
>
>    <context-param>
>        <param-name>contextConfigLocation</param-name>
>        <param-value>
>            classpath:app-context.xml
>            classpath:app-context-security.xml
>        </param-value>
>    </context-param>
>    <listener>
>        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
>    </listener>
>    <servlet>
>        <servlet-name>Jersey Spring Web Application</servlet-name>
>        <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
>        <load-on-startup>1</load-on-startup>
>    </servlet>
>    <servlet-mapping>
>        <servlet-name>Jersey Spring Web Application</servlet-name>
>        <url-pattern>/*</url-pattern>
>    </servlet-mapping>
>
> If it does not work please let me know I will try your example again later.
>
> Best regards,
>
> Imran
>
> On Tue, Mar 24, 2009 at 4:58 PM, Mats Henricson <Mats.Henricson_at_paf.com> wrote:
>> OK, here is what I want to do as a TDD developer. Sorry for
>> such a long email. I've tried to simplify my code as much as
>> possible for this post, and may have missed in cases.
>>
>> First lets assume I have a class used inside a Jersey resource
>> for its implementation:
>>
>> package foo;
>>
>> @Component
>> public class BarImpl implements Bar {
>>    public String getHello(long id) throws BarException {
>>
>>        if (id == -1) {
>>            throw new BarException("No such user: " + id);
>>        }
>>
>>        return "Hello " + id;
>>    }
>> }
>>
>> That BarException is in package foo.exceptions and totally trivial.
>> The Bar interface is also totally trivial.
>>
>> Now this is my resource class:
>>
>> package foo.resource;
>>
>> @Path("/hello")
>> @Component
>> public class BarResource {
>>
>>    @Autowired
>>    private Bar bar;
>>
>>    @GET
>>    @Produces("text/plain")
>>    public String getHello(@QueryParam("id") long id) throws BarException {
>>        return bar.getHello(id);
>>    }
>>
>>    public void setBar(Bar bar) {
>>        this.bar = bar;
>>    }
>> }
>>
>> Now, lets test this baby with JUnit. I write an applicationContext-test.xml:
>>
>> <?xml version="1.0" encoding="UTF-8"?>
>> <beans LOTS OF XML MUMBO JUMBO>
>>
>>  <bean id="bar" class="foo.BarImpl">
>>  </bean>
>>
>>  <bean id="barResource" class="foo.resource.BarResource">
>>    <property name="bar" ref="bar"/>
>>  </bean>
>> </beans>
>>
>> The JUnit test of the resource class is a beauty of simplicity:
>>
>> @RunWith(SpringJUnit4ClassRunner.class)
>> @ContextConfiguration(locations = { "/applicationContext-test.xml" })
>> public class BarResourceTest {
>>
>>    @Autowired
>>    private BarResource barResource;
>>
>>    @Test
>>    public void testWithBogusId() {
>>        try {
>>            /* IGNORE RETURNED VALUE */ barResource.getHello(-1);
>>            Assert.fail();
>>        }
>>        catch (BarException e) {
>>            String message = e.getMessage();
>>            Assert.assertEquals(message, "No such user: -1");
>>        }
>>    }
>>
>>    @Test
>>    public void testWithOkId() throws BarException {
>>        String message =  barResource.getHello(77);
>>        Assert.assertEquals(message, "Hello 77");
>>    }
>> }
>>
>> Now, how do I test this resource over HTTP? A complicating issue is that
>> I have an exception mapper:
>>
>> @Provider
>> public class BarExceptionMapper implements ExceptionMapper<BarException> {
>>
>>    public Response toResponse(BarException e) {
>>        return Response.status(Response.Status.NOT_FOUND).
>>               entity(e.toString()).type("text/plain").build();
>>    }
>> }
>>
>> My (probably totally naive) attempt was this, from looking all over the
>> net for examples:
>>
>> @RunWith(SpringJUnit4ClassRunner.class)
>> @ContextConfiguration(locations = { "/applicationContext-test.xml" })
>> public class BarResourceRestTest {
>>
>>    private static final String baseUri = "http://localhost:9998/";
>>    private static final String resourcePackage =
>>                                BarResource.class.getPackage().getName();
>>    private static final String exceptionMapperPackage =
>>                                BarExceptionMapper.class.getPackage().getName();
>>
>>    private SelectorThread threadSelector;
>>
>>    @Before
>>    public void setup() throws IllegalArgumentException, IOException {
>>        final Map<String, String> initParams = new HashMap<String, String>();
>>
>>        initParams.put("com.sun.jersey.config.property.packages",
>>                       resourcePackage + ";" + exceptionMapperPackage);
>>        initParams.put("com.sun.jersey.config.property.resourceConfigClass",
>>                       "com.sun.jersey.api.core.PackagesResourceConfig");
>>
>>        threadSelector = GrizzlyWebContainerFactory.create(baseUri, initParams);
>>    }
>>
>>    @After
>>    public void shutDown() {
>>        threadSelector.stopEndpoint();
>>    }
>>
>>    @Test
>>    public void testWithBogusId() throws IOException {
>>        URL url = new URL(baseUri + "hello/-1");
>>        String data = getDataFromUrl(url);
>>
>>        Assert.assertTrue(data.equals("No such user: -1"));
>>    }
>>
>>    @Test
>>    public void testWithOkId() throws IOException {
>>        URL url = new URL(baseUri + "hello/77");
>>        String data = getDataFromUrl(url);
>>
>>        Assert.assertTrue(data.equals("Hello 77"));
>>    }
>>
>>    private String getDataFromUrl(URL url) throws IOException {
>>        // Read all the text returned by the server
>>        BufferedReader in = new BufferedReader(
>>                                new InputStreamReader(url.openStream()));
>>        StringBuffer data = new StringBuffer(1000);
>>        String line;
>>
>>        while ((line = in.readLine()) != null) {
>>            data.append(line);
>>        }
>>
>>        in.close();
>>
>>        return data.toString();
>>    }
>> }
>>
>> I can't get this to work. I've fiddled with various things, and I either
>> get a NullPointer where the bar object is used in this function:
>>
>>    public String getHello(@QueryParam("id") long id) throws BarException {
>>        return bar.getHello(id);
>>    }
>>
>> Or, I get an exception, because the ExceptionMapper isn't in place.
>>
>> I clearly don't want to fiddle with web.xml. I just want to deploy my
>> resource in Grizzly (or whatever standalone container) and make an HTTP
>> call. I would also prefer not to embed GlassFish in my JUnit tests.
>> We use WebLogic, but not in our JUnit tests, of course.
>>
>> Mats
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>>
>
>
>
> --
> Imran M Yousuf
> Entrepreneur & Software Engineer
> Smart IT Engineering
> Dhaka, Bangladesh
> Email: imran_at_smartitengineering.com
> Blog: http://imyousuf-tech.blogs.smartitengineering.com/
> Mobile: +880-1711402557
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>



-- 
Imran M Yousuf
Entrepreneur & Software Engineer
Smart IT Engineering
Dhaka, Bangladesh
Email: imran_at_smartitengineering.com
Blog: http://imyousuf-tech.blogs.smartitengineering.com/
Mobile: +880-1711402557