You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by George Christman <gc...@cardaddy.com> on 2014/08/28 03:46:44 UTC

Unit test component with request parameter

Hi everyone, I'm trying to create some unit test against a new component
I'm working on. The new component uses request.getParameter(). I'm
wondering how I would go about setting the request parameter in my test
case.

Component I'm testing

public void keywordFacetSearch() {
        // Get the user's search keyword(s). Get optional parameters, or
apply default values if those parameters weren't passed.
        String searchString = request.getParameter(SearchParam.KEY) != null
? request.getParameter(CarDaddyEnum.KEY).trim() : "";
}

Test case

@Test
  public void testKeywordFacetSearch() {
        request.setAttribute(SearchParam.KEY, "foo");
  }

request.setAttribute doesn't seem to work. Any ideas?

Thanks

-- 
George Christman
www.CarDaddy.com
P.O. Box 735
Johnstown, New York

Re: Unit test component with request parameter

Posted by Lance Java <la...@googlemail.com>.
Looks like you've put a lot of thought into your urls.

> It would end up looking something like this.
domain.com
<http://domain.com/category/make/$N/$N/$N/$N/$N/$N/$N/$N/$N/$N/brown>
/category/make/$N/$N/$N/$N/$N/$N/$N/$N/$N/$N/brown
<http://domain.com/category/make/$N/$N/$N/$N/$N/$N/$N/$N/$N/$N/brown>

Haha... yeah... It's not suited to this use case. It works better when
there can only be trailing nulls (which don't appear in the url).

Re: Unit test component with request parameter

Posted by Thiago H de Paula Figueiredo <th...@gmail.com>.
On Thu, 28 Aug 2014 16:27:20 -0300, George Christman  
<gc...@cardaddy.com> wrote:

> Your absolutely correct, context URLs are much better for SEO than  
> request
> parameters. I tend to use both at the same time, example
> domain/category?make=ford, category being the context. I think what  
> you've
> done is a cool idea, however with the amount of filters that we will end  
> up
> having, it would get real messy when they are mostly all null. It would  
> end
> up looking something like this.
> domain.com/category/make/$N/$N/$N/$N/$N/$N/$N/$N/$N/$N/brown

You can avoid the $N by providing your own  
org.apache.tapestry5.services.URLEncoder.

> Some of the newer stuff I have planned will look something like this.
> http://www.cardaddy.com/used-cars/2011-toyota-corolla-le-albany-ny-12205-4978?_rd=50&color=brown

You could also map the other parameters into a single string and pass it  
as an activation context value. In this case, you'd need to do the string  
<-> parameters map yourself.

-- 
Thiago H. de Paula Figueiredo
Tapestry, Java and Hibernate consultant and developer
http://machina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: Unit test component with request parameter

Posted by George Christman <gc...@cardaddy.com>.
Your absolutely correct, context URLs are much better for SEO than request
parameters. I tend to use both at the same time, example
domain/category?make=ford, category being the context. I think what you've
done is a cool idea, however with the amount of filters that we will end up
having, it would get real messy when they are mostly all null. It would end
up looking something like this.
domain.com/category/make/$N/$N/$N/$N/$N/$N/$N/$N/$N/$N/brown

Some of the newer stuff I have planned will look something like this.
http://www.cardaddy.com/used-cars/2011-toyota-corolla-le-albany-ny-12205-4978?_rd=50&color=brown

used-cars = context param
2011-toyota-corolla-le-albany-ny-12205-4978 = context param
12095 = zipcode
4978 = db pk for the year make model trim combo.

We are already doing something similar on a smaller scale here.
http://www.cardaddy.com/forsale/vehicle/2011-toyota-corolla-le-duluth-ga-4978


On Thu, Aug 28, 2014 at 2:14 PM, Lance Java <la...@googlemail.com>
wrote:

> > I believe you were the one who use push me away from @Persist
> Lol... sounds like me :)
>
> I'm no SEO guru but I think keywords in the URL score better than request
> parameters. You might be interested in this recent feature I added to
> @PageActivationContext
>
> https://issues.apache.org/jira/browse/TAP5-2138
>



-- 
George Christman
www.CarDaddy.com
P.O. Box 735
Johnstown, New York

Re: Unit test component with request parameter

Posted by Lance Java <la...@googlemail.com>.
> I believe you were the one who use push me away from @Persist
Lol... sounds like me :)

I'm no SEO guru but I think keywords in the URL score better than request
parameters. You might be interested in this recent feature I added to
@PageActivationContext

https://issues.apache.org/jira/browse/TAP5-2138

Re: Unit test component with request parameter

Posted by George Christman <gc...@cardaddy.com>.
Yup you got it :) I believe you were the one who use push me away from
@Persist and build stateless apps lol.


On Thu, Aug 28, 2014 at 12:24 PM, Lance Java <la...@googlemail.com>
wrote:

> I've been making assumptions without viewing code :) Up until now I've been
> thinking it was an AJAX update.
>
> I'm now thinking you're doing a redirect after post and you're using
> request parameters to pass the values (avoiding @Persist and having
> bookmarkable urls).
>
> Sounds fine to me. The other option is to use activation context.
>



-- 
George Christman
www.CarDaddy.com
P.O. Box 735
Johnstown, New York

Re: Unit test component with request parameter

Posted by Lance Java <la...@googlemail.com>.
I've been making assumptions without viewing code :) Up until now I've been
thinking it was an AJAX update.

I'm now thinking you're doing a redirect after post and you're using
request parameters to pass the values (avoiding @Persist and having
bookmarkable urls).

Sounds fine to me. The other option is to use activation context.

Re: Unit test component with request parameter

Posted by George Christman <gc...@cardaddy.com>.
Wouldn't you still need to set the parameters to build the URL though? We
just need to be sure the filters remain in the URL so that the searches can
be book marked and indexed by search engines.


On Thu, Aug 28, 2014 at 10:46 AM, Lance Java <la...@googlemail.com>
wrote:

> > Im not sure I understand the differences between field values and event
> parameters
> field values - What I meant here was using a <t:form /> and binding
> properties to TextField and Select etc.
> event parameters - eg: onMyEvent(String param1, String param2, ...)
>
> Have you seen the filter demo of the observe plugin in tapestry-stitch?
> http://tapestry-stitch.uklance.cloudbees.net/observedemo
> It hides request parameters from you and converts to event parameters so
> your code can be cleaner.
>



-- 
George Christman
www.CarDaddy.com
P.O. Box 735
Johnstown, New York

Re: Unit test component with request parameter

Posted by Lance Java <la...@googlemail.com>.
> Im not sure I understand the differences between field values and event
parameters
field values - What I meant here was using a <t:form /> and binding
properties to TextField and Select etc.
event parameters - eg: onMyEvent(String param1, String param2, ...)

Have you seen the filter demo of the observe plugin in tapestry-stitch?
http://tapestry-stitch.uklance.cloudbees.net/observedemo
It hides request parameters from you and converts to event parameters so
your code can be cleaner.

Re: Unit test component with request parameter

Posted by George Christman <gc...@cardaddy.com>.
Ah okay, so I guess what you are suggesting is similar to what I originally
had. I'm not sure I understand the differences between field values and
event parameters. I just need to be able to read parameters from the URL.


On Thu, Aug 28, 2014 at 9:08 AM, Lance Java <la...@googlemail.com>
wrote:

> I'd do something like this to separate web from service and keep it
> testable.
>
> @Inject
> private MyService myService;
>
> public void doSearch(@RequestParam String filter1, @RequestParam Integer
> filter2) {
>    SearchFilter filter = new SearchFilter();
>    filter.setFilter1(filter1);
>    filter.setFilter2(filter2);
>
>    List<SearchResult> results = myService.doSearch(filter);
>    doStuff(results);
> }
>



-- 
George Christman
www.CarDaddy.com
P.O. Box 735
Johnstown, New York

Re: Unit test component with request parameter

Posted by Lance Java <la...@googlemail.com>.
I'd do something like this to separate web from service and keep it
testable.

@Inject
private MyService myService;

public void doSearch(@RequestParam String filter1, @RequestParam Integer
filter2) {
   SearchFilter filter = new SearchFilter();
   filter.setFilter1(filter1);
   filter.setFilter2(filter2);

   List<SearchResult> results = myService.doSearch(filter);
   doStuff(results);
}

Re: Unit test component with request parameter

Posted by Lance Java <la...@googlemail.com>.
@RequestParameter will only work for page and component events.

A robust service layer should never reference the Request or any other web
objects so you should really pass them through to the service. Perhaps you
want to encapsulate multiple values in a bean which can grow over time
without changing the service's method signature.

Is there a reason why you are using request parameters and not field values
or event parameters?

Re: Unit test component with request parameter

Posted by George Christman <gc...@cardaddy.com>.
Hi lance, I've been working on simplifying the design, so with that said
the service and page design is a little different from what I have checked
in. My goal is to remove all the request parameters from the page and put
them directly into the service so that I'm not having to pass them all over
the place.

So can I just add @Request Parameter to my service method signature and
both automatically read the request parameter from the url or just manually
pass it in through the the unit test? I'm not sure if thats what you were
suggesting.

I'm still very new to the mockito stuff, so I don't understand what it is
actually doing or how to use it.

I'm hoping to simplify the page class so that no testing is required.
Hopefully we can just test the services.
On Aug 28, 2014 3:18 AM, "Lance Java" <la...@googlemail.com> wrote:

> An even simpler approach is to grab the request parameter in the page /
> component and pass through to a service. Then forget about testing the page
> / component and focus on the service.
>
> This is what I usually do. A couple of lines of code go untested but my api
> is better and tests are much easier to maintain.
>

Re: Unit test component with request parameter

Posted by Lance Java <la...@googlemail.com>.
An even simpler approach is to grab the request parameter in the page /
component and pass through to a service. Then forget about testing the page
/ component and focus on the service.

This is what I usually do. A couple of lines of code go untested but my api
is better and tests are much easier to maintain.

Re: Unit test component with request parameter

Posted by Lance Java <la...@googlemail.com>.
Hi George, you're lucky I know your architecture :) You should include a
snippet of the test module for completeness.

You'll notice the request is actually a mockito proxy setup in the @Before
of the test (in the test module).

Can you use @RequestParameter in the event (instead of
request.getParameter()?) then you can call the method and pass a value from
the test.

Otherwise you'll need to use mockito to mock request.getParameter(...)
(similar to how request.isXhr() is currently mocked). You'll need to be
careful here, there are 2 request proxies (mockito proxy wrapped by
tapestry ioc proxy). And I'm not sure mockito methods can act on the
tapestry proxy.
On 28 Aug 2014 02:47, "George Christman" <gc...@cardaddy.com> wrote:

> Hi everyone, I'm trying to create some unit test against a new component
> I'm working on. The new component uses request.getParameter(). I'm
> wondering how I would go about setting the request parameter in my test
> case.
>
> Component I'm testing
>
> public void keywordFacetSearch() {
>         // Get the user's search keyword(s). Get optional parameters, or
> apply default values if those parameters weren't passed.
>         String searchString = request.getParameter(SearchParam.KEY) != null
> ? request.getParameter(CarDaddyEnum.KEY).trim() : "";
> }
>
> Test case
>
> @Test
>   public void testKeywordFacetSearch() {
>         request.setAttribute(SearchParam.KEY, "foo");
>   }
>
> request.setAttribute doesn't seem to work. Any ideas?
>
> Thanks
>
> --
> George Christman
> www.CarDaddy.com
> P.O. Box 735
> Johnstown, New York
>