Toby | 3 Aug 16:07 2009
Picon

Setting dependencies in servlets

Hello,

Probably a silly question really but what's the preferred way to set dependencies on a servlet so they can be mocked? Usually, I'd set them on the constructor of some object and have the servlet delegate to that object but I find myself writing an integration type test where the servlet itself is being tested... I'm assuming you'd set any configuration (ie the dependancies) on the servlet context and mock some servlet API call to return the mocked dependency? I'm wondering if I've forgotten some nifty trick though as that just seems clunky!

Cheers,
--
Toby

Nat Pryce | 3 Aug 20:28 2009
Picon

Re: Setting dependencies in servlets

The servlet API is clunky.

I prefercto treat servlets as a thin-as-possible layer between the
HTTP server and my code, which has objects with real constructors and
clear dependencies. I unit test those objects and write integration
tests to ensure that the webapp initialises and hooks them up
correctly.

Even better, I find, is not to stick too closely to the servlet API
and just use the Jetty HTTP engine embedded in simple main app. That
allows me to write servlets that have constructors and avoid the whole
servlet-context/web-app-lifecycle-listener mess.

--Nat

On Monday, August 3, 2009, Toby <toby.weston@...> wrote:
> Hello,
>
> Probably a silly question really but what's the preferred way to set dependencies on a servlet so they can
be mocked? Usually, I'd set them on the constructor of some object and have the servlet delegate to that
object but I find myself writing an integration type test where the servlet itself is being tested... I'm
assuming you'd set any configuration (ie the dependancies) on the servlet context and mock some servlet
API call to return the mocked dependency? I'm wondering if I've forgotten some nifty trick though as that
just seems clunky!
>
> Cheers,
> --
> Toby
>

--

-- 
http://www.natpryce.com

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email

Toby | 3 Aug 21:52 2009
Picon

Re: Setting dependencies in servlets

Cheers, that's pretty much what I'd figured. It's interesting though  
trying to test that *just* things are wired up correctly in the  
servlet without overlapping too much with the unit tests you describe.

Thanks again :)

Toby

On 3 Aug 2009, at 19:28, Nat Pryce <nat.pryce@...> wrote:

> The servlet API is clunky.
>
> I prefercto treat servlets as a thin-as-possible layer between the
> HTTP server and my code, which has objects with real constructors and
> clear dependencies. I unit test those objects and write integration
> tests to ensure that the webapp initialises and hooks them up
> correctly.
>
> Even better, I find, is not to stick too closely to the servlet API
> and just use the Jetty HTTP engine embedded in simple main app. That
> allows me to write servlets that have constructors and avoid the whole
> servlet-context/web-app-lifecycle-listener mess.
>
> --Nat
>
> On Monday, August 3, 2009, Toby <toby.weston@...> wrote:
>> Hello,
>>
>> Probably a silly question really but what's the preferred way to  
>> set dependencies on a servlet so they can be mocked? Usually, I'd  
>> set them on the constructor of some object and have the servlet  
>> delegate to that object but I find myself writing an integration  
>> type test where the servlet itself is being tested... I'm assuming  
>> you'd set any configuration (ie the dependancies) on the servlet  
>> context and mock some servlet API call to return the mocked  
>> dependency? I'm wondering if I've forgotten some nifty trick though  
>> as that just seems clunky!
>>
>> Cheers,
>> --
>> Toby
>>
>
> -- 
> http://www.natpryce.com
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email

chris | 5 Aug 11:38 2009

Re: Sharing/Reusing Expectations across tests.

Nat,

thanks for the responses.

> It sounds like you're focusing the test on the wrong thing. I would
> not write a test for each "step" in the process method.  Rather I'd
> focus it on each feature of the object as far as the client is
> concerned, running (and testing) the entire process method from entry
> to exit in each test.

When each step is a logical function then this is where the problem is.

My current code looks like this roughly:

    public boolean process(Set<? extends TypeElement> annotations,
                           RoundEnvironment roundEnv) {
        // For each annotation type to be processed.
        for (TypeElement annotation : annotations) {
            // For each annotated element.
            for (Element element :
roundEnv.getElementsAnnotatedWith(annotation)) {
                // If the annotated element is a class.
                if (element.getKind().isClass()) {
                    // Process class element.
                    processClassElement(element);
                }
            }
        }

        // Always a true response
        return true;
    }

    /**
     * Process a class element.
     *
     *  <at> param element Class element.
     */
    private void processClassElement(Element element) {
        processSource(element);
        // If there are class processors.
        if (this.classProcessors != null) {
            // with each class processor.
            for (ElementProcessor elementProcessor : this.classProcessors) {
                // ###### JUST ADDED THIS
                elementProcessor.setProcessingEnvironment(this.processingEnv);
                // Inject the source code reader.
                elementProcessor.setSourceCodeReader(this.sourceCodeReader);
                // Process this element.
                elementProcessor.process(element);
            }
        }
        else {
            // Raise compiler warning.
            this.processingEnv.getMessager().printMessage(
                    Diagnostic.Kind.WARNING, "No class processors found");
        }
    }

    /**
     * Processes the source code for a class element.
     *
     *  <at> param element The class element.
     */
    private void processSource(Element element) {
        try {
            // Try and process any source file attached to the class element.
            Source source = this.sourceCodeReader.getSource(element);
            this.sourceCodeProcessor.setSource(source);
            this.sourceCodeProcessor.process();
        }
        catch (SourceReaderException e) {
            // Raise compiler warning.
            this.processingEnv.getMessager().printMessage(
                    Diagnostic.Kind.WARNING, "Problem reading source code");
        }
        catch (SourceProcessorException e) {
            // Raise compiler warning.
            this.processingEnv.getMessager().printMessage(
                    Diagnostic.Kind.WARNING, "Problem processing source
code");
        }
    }

Now I have tests which assert that each collaborator is invoked as
expected because I need to be
sure that this behaviour is always carried out.

And I have tests to make sure that exceptions thrown at any point are
handled correctly.

Every step above is carried out when the process() method is invoked. This
is part of the Java API
which I have no access to changing so need to accept. A list of mocks is
passed in, which is then
broken down into another list of mocks, which then a bunch of stuff need
to be done with.

So for an example, the test which gets to the end of the process looks like

   /**
     * Tests that the source code is processed.
     */
     <at> Test(groups = "unit")
    public void testSourceIsProcessed()
            throws SourceReaderException, SourceProcessorException {

        // Set up expectations.
        this.mockery.checking(new Expectations() {
            {
                // Get all annotated elements for this annotation.
                allowing(roundEnvironment).getElementsAnnotatedWith(annotation);
                will(returnValue(elements));

                // The first element is a class.
                allowing(element).getKind();
                will(returnValue(ElementKind.CLASS));

                // Ignore the class processor for this test.
                ignoring(classProcessor);

                // Expect the source code reader to return source object.
                allowing(sourceCodeReader).getSource(element);
                will(returnValue(source));

                // Ignore.
                ignoring(sourceCodeProcessor).setSource(source);

                // Process the source.
                oneOf(sourceCodeProcessor).process();
            }
        });

        // Process.
        this.coreClassElementProcessor.process(this.annotations,
                this.roundEnvironment);
    }

Where the process() on the source code processor is invoked is my
(current) final step.

So I have now came across a step in one of my collaborators where an
object in the parent
is required so I have added the bit above which says

                // ###### JUST ADDED THIS
                elementProcessor.setProcessingEnvironment(this.processingEnv);

My main question is, in order to add this one line, every single test now
fails with

"unexpected invocation:
elementProcessor.setProcessingEnvironment(<processingEnvironment>)"

So I then need to add the following to every single failing test.

// Ignore.
ignoring(elementProcessor).setProcessingEnvironmen(processingEnvironment);

So my tests are growing with all these "ignore" expectations, which is
making the tests look
complicated and unreadable. Regardless of what I focus my testing on, I am
still going to need
to ignore everything that happened before it.

And my class is very basic. I dont think this class can be made finer
grained without further
convoluting things.

I hope what I have written makes sense there, my head is spinning a little.

Chris

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email

Mattias Jiderhamn | 6 Aug 14:37 2009
Picon

Get hold of parameter to mocked object

What is the recommended practice for getting hold of the parameter
passed to a mock object, for further testing.

An example of what I want to do:

  OrderDAO orderDAO = context.mock(OrderDAO.class);

  checking(new Expectations() {
      {
        oneOf(orderDAO).save(with(any(Order.class)));
      }
    });

  doSomethingThatCreatesAndSavesOrder();

  Order order = ...; // The order passed to the mocked OrderDAO.save()

  // Regular jUnit tests
  assertEquals("1", order.getCustomer());
  assertEquals(3, order.getNoOfLines());
  ...

I know I can do this using custom matchers:

 ...
  oneOf(orderDAO).save(with(allOf(
      any(Order.class),
      Matchers.hasProperty("customer",
org.hamcrest.CoreMatchers.equalTo("1") // (Need to be declared as local
variable for generics to work)
  )));
 ...

but if the test fails, the error does not include the specific test that
failed but only an "unexpected invocation".

The solution that I have come up with would be to create a Matcher that
remembers the object it is asked to match, which could then be accessed
for further testing.
Seems a bit ugly though. My gut tells me somebody should have thought
about this already.
Is there a better way???

--

-- 

  </Mattias>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email

chris | 6 Aug 14:51 2009

Re: Get hold of parameter to mocked object

Mattias,

In my experience, are you sure thats what you want to be testing for?

You should only be expecting that the DAO's "save" is being invoked with
the order.

Anything further would then be getting tested in the implementation's test
class i.e. "OrderDAOImplTest", and not in this test.

Sorry if I have misunderstood your intentions.

Chris

> What is the recommended practice for getting hold of the parameter
> passed to a mock object, for further testing.
>
> An example of what I want to do:
>
>   OrderDAO orderDAO = context.mock(OrderDAO.class);
>
>   checking(new Expectations() {
>       {
>         oneOf(orderDAO).save(with(any(Order.class)));
>       }
>     });
>
>   doSomethingThatCreatesAndSavesOrder();
>
>   Order order = ...; // The order passed to the mocked OrderDAO.save()
>
>   // Regular jUnit tests
>   assertEquals("1", order.getCustomer());
>   assertEquals(3, order.getNoOfLines());
>   ...
>
> I know I can do this using custom matchers:
>
>  ...
>   oneOf(orderDAO).save(with(allOf(
>       any(Order.class),
>       Matchers.hasProperty("customer",
> org.hamcrest.CoreMatchers.equalTo("1") // (Need to be declared as local
> variable for generics to work)
>   )));
>  ...
>
> but if the test fails, the error does not include the specific test that
> failed but only an "unexpected invocation".
>
> The solution that I have come up with would be to create a Matcher that
> remembers the object it is asked to match, which could then be accessed
> for further testing.
> Seems a bit ugly though. My gut tells me somebody should have thought
> about this already.
> Is there a better way???
>
> --
>
>   </Mattias>
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>     http://xircles.codehaus.org/manage_email
>
>
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email

Mattias Jiderhamn | 6 Aug 15:07 2009
Picon

Re: Get hold of parameter to mocked object

I think that is what I want to do.

To put some more details into my example, I want to test business logic.
The output of the business logic is new/updated data, stored via DAOs.
There is no return value or anything else to test on.
Say for example that I want to verify that OrderCreator.createOrder(1,
2, 3) actually does create an order for customer 1 ordering article no.
2 at a quantity of 3.
My plan was to use jMock (since there is a lot of supporting DAO
communication going on in the actual business logic), and after calling
the method I want the test to examine the resulting Order instance which
was passed to the (mocked) OrderDAO by the tested business logic.

Is this not the way to go?
Do I need to create a dummy implementation of the DAO instead, that does
assertions in its save() implementation???

(I agree that the test of the DAO implementation is a totally different
matter)

  </Mattias> 

chris@... wrote (2009-08-06 14:51):
> Mattias,
>
> In my experience, are you sure thats what you want to be testing for?
>
> You should only be expecting that the DAO's "save" is being invoked with
> the order.
>
> Anything further would then be getting tested in the implementation's test
> class i.e. "OrderDAOImplTest", and not in this test.
>
> Sorry if I have misunderstood your intentions.
>
> Chris
>
>   
>> What is the recommended practice for getting hold of the parameter
>> passed to a mock object, for further testing.
>>
>> An example of what I want to do:
>>
>>   OrderDAO orderDAO = context.mock(OrderDAO.class);
>>
>>   checking(new Expectations() {
>>       {
>>         oneOf(orderDAO).save(with(any(Order.class)));
>>       }
>>     });
>>
>>   doSomethingThatCreatesAndSavesOrder();
>>
>>   Order order = ...; // The order passed to the mocked OrderDAO.save()
>>
>>   // Regular jUnit tests
>>   assertEquals("1", order.getCustomer());
>>   assertEquals(3, order.getNoOfLines());
>>   ...
>>
>> I know I can do this using custom matchers:
>>
>>  ...
>>   oneOf(orderDAO).save(with(allOf(
>>       any(Order.class),
>>       Matchers.hasProperty("customer",
>> org.hamcrest.CoreMatchers.equalTo("1") // (Need to be declared as local
>> variable for generics to work)
>>   )));
>>  ...
>>
>> but if the test fails, the error does not include the specific test that
>> failed but only an "unexpected invocation".
>>
>> The solution that I have come up with would be to create a Matcher that
>> remembers the object it is asked to match, which could then be accessed
>> for further testing.
>> Seems a bit ugly though. My gut tells me somebody should have thought
>> about this already.
>> Is there a better way???
>>
>> --
>>
>>   </Mattias>
>>     

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email

Julian Hall | 6 Aug 15:20 2009
Picon

Re: Get hold of parameter to mocked object

Mattias Jiderhamn wrote:
> What is the recommended practice for getting hold of the parameter
> passed to a mock object, for further testing.
>
> An example of what I want to do:
>
>   OrderDAO orderDAO = context.mock(OrderDAO.class);
>  
>   checking(new Expectations() {
>       {
>         oneOf(orderDAO).save(with(any(Order.class)));
>       }
>     });
>
>   doSomethingThatCreatesAndSavesOrder();
>
>   Order order = ...; // The order passed to the mocked OrderDAO.save()
>
>   // Regular jUnit tests
>   assertEquals("1", order.getCustomer());
>   assertEquals(3, order.getNoOfLines());
>   ...
>
> I know I can do this using custom matchers:
>
>  ...
>   oneOf(orderDAO).save(with(allOf(
>       any(Order.class),
>       Matchers.hasProperty("customer",
> org.hamcrest.CoreMatchers.equalTo("1") // (Need to be declared as local
> variable for generics to work)
>   )));
>  ...
>
> but if the test fails, the error does not include the specific test that
> failed but only an "unexpected invocation".
>
> The solution that I have come up with would be to create a Matcher that
> remembers the object it is asked to match, which could then be accessed
> for further testing.
> Seems a bit ugly though. My gut tells me somebody should have thought
> about this already.
> Is there a better way???
>   
I think doing it via an action is cleaner.  See 
http://thread.gmane.org/gmane.comp.java.jmock.user/2278/focus=2284 for 
my class that does this.

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email

chris | 6 Aug 15:21 2009

Re: Get hold of parameter to mocked object

Mattias,

I think I understand what you mean.

This is just my opinion, but from my personal learning experience, if a
piece of behaviour is not easily testable, it probably means the code
needs to be refactored. This is what TDD excels at forcing you to.
refactoring possible poor design.

To me, because this is not easily testable it highlights that your
business logic should not be interested in checking that the values of
domain objects are correct.

Your method should probably just be:

OrderCreator.createOrder(order);

and then assert that the order creates calls save on the DAO.

Setting the values of your domain object POJO (order) should probably be
done in a much higher level such as a Struts action, or Servlet.

And when you test your DAO you can test

1. That all the values nessessary in the domain object have been set to
legal/acceptable values.

or

2. That exceptions from your persistance framework are correctly handled
if a POJO is passed with illegal values.

Thats the kinda way we do it in here.

Chris

> I think that is what I want to do.
>
> To put some more details into my example, I want to test business logic.
> The output of the business logic is new/updated data, stored via DAOs.
> There is no return value or anything else to test on.
> Say for example that I want to verify that OrderCreator.createOrder(1,
> 2, 3) actually does create an order for customer 1 ordering article no.
> 2 at a quantity of 3.
> My plan was to use jMock (since there is a lot of supporting DAO
> communication going on in the actual business logic), and after calling
> the method I want the test to examine the resulting Order instance which
> was passed to the (mocked) OrderDAO by the tested business logic.
>
> Is this not the way to go?
> Do I need to create a dummy implementation of the DAO instead, that does
> assertions in its save() implementation???
>
> (I agree that the test of the DAO implementation is a totally different
> matter)
>
>   </Mattias>
>
>
> chris@... wrote (2009-08-06 14:51):
>> Mattias,
>>
>> In my experience, are you sure thats what you want to be testing for?
>>
>> You should only be expecting that the DAO's "save" is being invoked with
>> the order.
>>
>> Anything further would then be getting tested in the implementation's
>> test
>> class i.e. "OrderDAOImplTest", and not in this test.
>>
>> Sorry if I have misunderstood your intentions.
>>
>> Chris
>>
>>
>>> What is the recommended practice for getting hold of the parameter
>>> passed to a mock object, for further testing.
>>>
>>> An example of what I want to do:
>>>
>>>   OrderDAO orderDAO = context.mock(OrderDAO.class);
>>>
>>>   checking(new Expectations() {
>>>       {
>>>         oneOf(orderDAO).save(with(any(Order.class)));
>>>       }
>>>     });
>>>
>>>   doSomethingThatCreatesAndSavesOrder();
>>>
>>>   Order order = ...; // The order passed to the mocked OrderDAO.save()
>>>
>>>   // Regular jUnit tests
>>>   assertEquals("1", order.getCustomer());
>>>   assertEquals(3, order.getNoOfLines());
>>>   ...
>>>
>>> I know I can do this using custom matchers:
>>>
>>>  ...
>>>   oneOf(orderDAO).save(with(allOf(
>>>       any(Order.class),
>>>       Matchers.hasProperty("customer",
>>> org.hamcrest.CoreMatchers.equalTo("1") // (Need to be declared as local
>>> variable for generics to work)
>>>   )));
>>>  ...
>>>
>>> but if the test fails, the error does not include the specific test
>>> that
>>> failed but only an "unexpected invocation".
>>>
>>> The solution that I have come up with would be to create a Matcher that
>>> remembers the object it is asked to match, which could then be accessed
>>> for further testing.
>>> Seems a bit ugly though. My gut tells me somebody should have thought
>>> about this already.
>>> Is there a better way???
>>>
>>> --
>>>
>>>   </Mattias>
>>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>     http://xircles.codehaus.org/manage_email
>
>
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email

Steve Freeman | 6 Aug 15:32 2009
Picon

Re: Get hold of parameter to mocked object

On 6 Aug 2009, at 14:20, Julian Hall wrote:
> Mattias Jiderhamn wrote:
>> The solution that I have come up with would be to create a Matcher  
>> that
>> remembers the object it is asked to match, which could then be  
>> accessed
>> for further testing.
>> Seems a bit ugly though. My gut tells me somebody should have thought
>> about this already.
>> Is there a better way???
>>
> I think doing it via an action is cleaner.  See
http://thread.gmane.org/gmane.comp.java.jmock.user/2278/focus=2284 
>  for my class that does this.

If you want to stash a parameter, then an Action is the place to do  
it--but it's almost certainly the wrong thing to do.

S

Steve Freeman
Winner of the Agile Alliance Gordon Pask award 2006

http://www.m3p.co.uk

M3P Limited.
Registered office. 2 Church Street, Burnham, Bucks, SL1 7HZ.
Company registered in England & Wales. Number 03689627

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Gmane