I am using glassfish application server. I need to write the junits for some servlet. My question here is how can i create simulated container, mock request and response with core java libraries or i need to use some kind of tool here ?Any pointers would be helpful?
As hvgotcodes notes, it's entirely possible to write JUnit tests for servlets. But I'd advise you to think carefully before you do so.
Servlets are HTTP request listeners; they run in a servlet container, respond to any HTTP requests that come their way, and package up results to send back. That's all they should be doing, in my opinion. The real work is best left to other objects that the servlet can marshal. These can be POJOs, most likely interface-based, which will mean easier testing without having to start up a servlet container to run the test. If you decide that you need the same functionality in a non-web-based setting, it's easy to do because it already resides in objects other than a servlet.
I'd reconsider the design. Putting a lot of functionality in a servlet might be a bad decision.
1) Its not a bad idea to abstract your application logic into objects that are called by the servlet, so you can test your business logic separate from your servlet interactions.
2) Spring provides some mock classes for tests, including requests and responses. Even if you are not using Spring, you can still use those classes just for tests.
You may find Arquillian from JBoss interesting - http://community.jboss.org/wiki/Arquillian.
Test in-container!
Arquillian provides a easy mechanism to test your application code inside a remote or embedded container or by interacting as a client of the container.
Mission Statement
The mission of the Arquillian project is to provide a simple test harness that developers can use to produce a broad range of integration tests for their Java applications (most likely enterprise applications). A test case may be executed within the container, deployed alongside the code under test, or by coordinating with the container, acting as a client to the deployed code.
Related
I recently managed to convince my mates in the project that we need testing (!). Due to the highly dynamic and flexible structure of our web application, with behavior depending of lots of parameters and permission relationships, they had rejected testing altogether, for the usual reasons (time consuming, test maintenance, etc.).
We will introduce testing at the service layer:
Web Browser -> GWT/RPC -> GWT Servlet -> RMI -> SessionEJB -> RMI -> Spring beans
Thus after the GWT Servlet.
Do people recommend to use junit? Or are there other test frameworks better suited? Any other general suggestions? Thanks
You can indeed use plain JUnit or TestNG with a mock framework to test your SessionEJB and individual Spring beans in isolation, i.e. proper Unit testing.
But since there is already a lot of code written, you'll probably find more bugs with less code using system testing or integration testing, i.e. test your complete SessionEJB and spring beans roundtrip in a test application context, with even a real database behind.
For integration and system testing, you can use DBUnit to have a fixture of test data in a database. And Spring also has a lot of test support utils. All of this things work with both JUnit and TestNG.
You should be able to JUnit your Servlets & EJBs. I suggest using some kind of mock framework (e.g. EasyMock) for your servlet context and if you are using any kind of JNDI resource or dependency injection.
As for a testing framework, I highly recommend TestNG (http://testng.org), with Mockito (code.google.com/p/mockito/). I love using both due to their ease of use. #DataProvider in TestNG helps me a lot, as well as other annotations for setting up a test before/after running. I was using JUnit before until I met TestNG at work and don't think I'll be going back anytime soon :)
Check them out, TestNG is definitely picking up some steam and gaining reputation.
I am currently having issues because the WebServiceContext is not initialised, obviously because the unit test is not within the EJB container. Is there anyway to manually create a WebServiceContext for testing purposed?
I found that actually testing the EJB within a container and making it run properly across platforms and tools (e.g. code coverage) is quite difficult at best and really slow in terms of execution performance.
Rather than executing the unit test in a container, you can focus more on the business logoc side and manually inject the needed components and run the #PostConstruct manually as part of your unit test harness then test your business logic.
You can use OpenEJB for that. Take a look at this stackoverflow thread:
Test #Webservice EJBs with WebServiceContext (using OpenEJB?)
You can also unit test in GlassFish Server 3 (it's backwards compatible with Java EE 5).
for some testing purposes it would be great not having to restart my jetty server for every test run.
With jrebel i can apply source changes directly.
Is it possible to run my jetty server in a way that i could inject changes dynamically and then rerun the tests without having to restart the server?
It depends on the kind of changes that you want to inject.
That said, I believe there is a deeper issue here. Restarting Jetty is the right thing to do from a test-quality standpoint. It ensures that each test starts from a clean page thereby minimizing the risk of inter-test dependencies. On the other hand, this is costly (time-wise) and make your suite runs slower.
If I were you, I would address this as follows: I will refactor the code that I want to test (presumably: servlets) such that they do not depend on the Jetty infrastructure, and can run stand-alone. For instance, If I have a servlet class SomeServlet with its doGet() method, I will refactor it such that it implement MyServelt whose goGet() takes a MyRequest, MyResponse parameters.
Once you do that, you can unit-test MyServlet without a Jetty server. This will allow you not only to test faster, but also ease your debugging sessions and make your components more decoupled. Of course, you will need to add some plumbing code: a class that adapts the servelt interface to a MyServelt object (via delegation).
Can you separate components of an IceFaces application so they can be tested in isolation instead of using something like Selenium or HttpUnit on the assembled application?
Backing beans can be easily isolated (if written to be testable) but I am interested in testing the template/display parts of the application while using as little of the rest of the application as possible. Can this be done? How?
Is there a way to render an IceFaces object as text using "dummy data" that I can then run through traditional unit tests?
I can think of ways to do all of this, but they involve creating multiple applications (one for each component I wish to test). However, this seems like a sub-optimal way of doing things.
If I understand your question correctly, then it ought to be a simple matter of creating special dummy backing beans for your pages, and then creating a test JSF configuration file mapping those beans to the .jspx files. The dummy beans, of course, won't touch any business logic or back-end services -- they'll simply be simple sets of data that will be easy to verify in your tests.
Create an ant script to substitute in your dummy backing beans and the test config file. Run your tests. If you don't want something as heavy as HTTPUnit, and if you're using Spring in your app, look at this blog post for an excellent way to mock up a full web context without a web server. Your tests will probably need to sniff the raw HTML output to verify the results. This is going to be tricky, because IceFaces loves to munge DIV IDs and other relevant parts of the DOM tree that you may want to sniff for. (This alone may be the reason why very few JSF developers try to unit test JSF output.)
Once your tests are verified, swap the regular beans and config file back into the app.
Voila! You've just unit-tested your JSF components.
Mind you, the whole business of swapping out beans and config files is messy. It would be much, much easier if IceFaces used Spring to match backing beans to JSF pages -- then you could simply define the test-beans in an application.xml with the relevant test classes. But such is life.
Good luck, and let me know how it works out for you!
This is not what exactly what you are asking for but JSFUnit (which uses JUnit, Cactus, HtmlUnit, and HttpUnit) seems to be a serious candidate for testing in the JSF land. Did you consider this option? Maybe have a look at the JSFUnit Wiki and its Getting Started Guide.
Please note that the FAQ is reporting some problems with IceFaces but its pretty old (early 2009) and the situation might have changed since then (there are some demo projects like jboss-jsfunit-examples-icefaces or icefaces-demo-address in JBoss repository so it may be worth to ask the exact status either on JSFUnit or IceFaces mailing lists).
EDIT: As mentioned in a comment, the OP is looking for something less "high level". Maybe have a look at the Shale Test Framework:
The Shale Test Framework provides mock
object libraries, plus base classes
for creating your own JUnit TestCases.
Mock objects are provided in package
org.apache.shale.test.mock for the
following container APIs:
JavaServer Faces
Servlet
Disclaimer: Apache Shale moved into the Attic in May 2009 (i.e. it has reached its end of life) but I don't know any other "mature" mock framework for JSF so I'm mentioning it anyway (the code is still there). I'll follow this thread with a very high interest for other solutions :)
first time poster and TDD adopter. :-) I'll be a bit verbose so please bear with me.
I've recently started developing SOAP based web services using the Apache CXF framework, Spring and Commons Chain for implementing business flow. The problem I'm facing here is with testing the web services -- testing as in Unit testing and functional testing.
My first attempt at Unit testing was a complete failure. To keep the unit tests flexible, I used a Spring XML file to keep my test data in. Also, instead of creating instances of "components" to be tested, I retrieved them from my Spring Application context. The XML files which harbored data quickly got out of hand; creating object graphs in XML turned out to be a nightmare. Since the "components" to be tested were picked from the Spring Application Context, each test run loaded all the components involved in my application, the DAO objects used etc. Also, as opposed to the concept of unit test cases being centralized or concentrated on testing only the component, my unit tests started hitting databases, communicating with mail servers etc. Bad, really bad.
I knew what I had done wrong and started to think of ways to rectify it. Following an advice from one of the posts on this board, I looked up Mockito, the Java mocking framework so that I could do away with using real DAO classes and mail servers and just mock the functionality.
With unit tests a bit under control, this brings me to my second problem; the dependence on data. The web services which I have been developing have very little logic but heavy reliance on data. As an example, consider one of my components:
public class PaymentScheduleRetrievalComponent implements Command {
public boolean execute(Context ctx) {
Policy policy = (Policy)ctx.get("POLICY");
List<PaymentSchedule> list = billingDAO.getPaymentStatementForPolicy(policy);
ctx.put("PAYMENT_SCHEDULE_LIST", list);
return false;
}
}
A majority of my components follow the same route -- pick a domain object from the context, hit the DAO [we are using iBatis as the SQL mapper here] and retrieve the result.
So, now the questions:
- How are DAO classes tested esp when a single insertion or updation might leave the database in a "unstable" state [in cases where let's say 3 insertions into different tables actually form a single transaction]?
- What is the de-facto standard for functional testing web services which move around a lot of data i.e. mindless insertions/retrievals from the data store?
Your personal experiences/comments would be greatly appreciated. Please let me know in case I've missed out some details on my part in explaining the problem at hand.
-sasuke
I would stay well away from the "Context as global hashmap" 'pattern' if I were you.
Looks like you are testing your persistence mapping...
You might want to take a look at: testing persistent objects without spring
I would recommend an in-memory database for running your unit tests against, such as HSQL. You can use this to create your schema on the fly (for example if you are using Hibernate, you can use your XML mappings files), then insert/update/delete as required before destroying the database at the end of your unit test. At no time will your test interfere with your actual database.
For you second problem (end-to-end testing of web services), I have successfully unit tested CXF-based services in the past. The trick is to publish your web service using a light-weight web server at the beginning of your test (Jetty is ideal), then use CXF to point a client to your web service endpoint, run your calls, then finally shut down the Jetty instance hosting your web service once your unit test has completed.
To achive this, you can use the JaxWsServerFactoryBean (server-side) and JaxWsProxyFactoryBean (client-side) classes provided with CXF, see this page for sample code:
http://cwiki.apache.org/CXF20DOC/a-simple-jax-ws-service.html#AsimpleJAX-WSservice-Publishingyourservice
I would also give a big thumbs up to SOAP UI for doing functional testing of your web service. JMeter is also extremely useful for stress testing web services, which is particularity important for those services doing database lookups.
First of all: Is there a reason you have to retrieve the subject under test (SUT) from the Spring Application context? For efficient unit testing you should be able to create the SUT without the context. It sounds like you have some hidden dependencies somewhere. That might be the root of some of your headache.
How are DAO classes tested esp when a
single insertion or updation might
leave the database in a "unstable"
state [in cases where let's say 3
insertions into different tables
actually form a single transaction]?
It seems you are worried about the database's constistency after you have running the tests. If possible use a own database for testing, where you don't need care about it. If you have such a sandbox database you can delete data as you wish. In this case I would do the following:
Flag all your fake data with some common identifier, like putting a special prefix to a field.
Before running the test drop a delete statement, which deletes the flagged data. If there is none, then nothing bad happens.
Run your single DAO test. After that repeat step 2. for the next test.
What is the de-facto standard for
functional testing web services which
move around a lot of data i.e.
mindless insertions/retrievals from
the data store?
I am not aware of any. From the question your are asking I can infer that you have on one side the web service and on the other side the database. Split up the responsibilities. Have separate test suites for each side. One side just testing database access (as described above). On the other side just testing web service requests and responses. In this case it pays of the stub/fake/mock the layer talking to the network. Or consider https://wsunit.dev.java.net/.
If the program is only shoving data in and out I think that there is not much behavior. If this is the case, then the hardest work is to unit test the database side and the web service side. The point is you can do unit testing without the need for "realistic" data. For functional testing you will need handrolled data, which is close to reality. This might be cumbersome, but if you already unit tested the database and web service parts intensively, this should reduce the need for "realistic" test cases considerably.
First of all, make thing clear.
In an ideal world the lifecycle of the software your are building is something like this:
- sy makes a report with the customer, so you got an user story with examples about how the application should work
- you generalize the user story, so you got rules, which you call as use cases
- you start to write a piece of functional (end to end) test, and it fails...
- after that your build the ui and mock out the services, so you got a green functional test and a specification about how your services should work...
- your job is to keep the functional test green, and implement the services step by step writing integration tests, and mocking out dependencies with the same approach until you reach the level of unit tests
- after that you do the next iteration with the use cases, write the next piece of functional test, and so on until the end of the project
- after that you make acceptance tests with the customer who accepts the product and pays a lot
So what did we learn from this:
There are many types of tests (don't confuse them with each other)
functional tests - for testing the use cases (mock out nothing)
integration tests - for testing application, component, module, class interactions (mock out the irrelevant components)
unit tests - for testing a single class in isolation from its environment (mock out everything)
user acceptance tests - customer makes sure, that she accepts the product (manual functional tests, or presentation made from automatic functional tests in working)
You don't need to test everything by functional tests and integration tests, because it is impossible. Test only the relevant part by functional and integration tests and test everything by unit tests! Familiarize yourself with the testing pyramid.
Use TDD, it makes life easier!
How are DAO classes tested esp when a single insertion or updation might leave the database in a "unstable" state [in cases where let's
say 3 insertions into different tables actually form a single
transaction]?
You don't have to test your database transactions. Assume, that they are working well, because database developers have already tested them, and I am sure you don't want to write concurrency tests... Db is an external component, so you don't have to test it yourself. You can write a data access layer to adapt the data storage to your system, and write integration tests only for those adapters. In case of database migration these tests will work by the adapters of the new database as well, because your write them to implement a specific interface... By any other tests (except functional tests) you can mock out your data access layer. Do the same with every other external component as well, write adapters and mock them out. Put these kind of integration tests to a different test suite than the other tests, because they are slow because of database access, filesystem access, etc...
What is the de-facto standard for functional testing web services which move around a lot of data i.e. mindless insertions/retrievals
from the data store?
Your can mock out your data store with an in memory db which implements the same storage adapters until you implemented everything else except the database. After that your implement the data access layer for the database and test it with your functional tests as well. It will be slow, but it has to run only once, for example by every new release... If you need functional tests by developing, you can mock it out with an in memory solution again... An alternative approach to run only the affected functional tests by developing, or modify the settings of the test db to make things faster, and so on... I am sure there are many test optimization solutions...
I must say I don't really understand
your exact problem. Is the problem
that your database is left in an
altered state after you've run the
test?
Yes, there are actually two issues here. First one being the problem with the database left in an inconsistent state after running the test cases. The second one being that I'm looking for an elegant solution in terms of end-to-end testing of web services.
For efficient unit testing you should
be able to create the SUT without the
context. It sounds like you have some
hidden dependencies somewhere. That
might be the root of some of your
headache.
That indeed was the root cause of my headaches which I am now about to do away with with the help of a mocking framework.
It seems you are worried about the
database's constistency after you have
running the tests. If possible use a
own database for testing, where you
don't need care about it. If you have
such a sandbox database you can delete
data as you wish.
This is indeed one of the solutions to the problem I mentioned in my previous post but this might not work in all the cases esp when integrating with a legacy system in which the database/data isn't in your control and in cases when some DAO methods require a certain data to be already present in a given set of tables. Should I look into database unit testing frameworks like DBUnit?
In this case it pays of the
stub/fake/mock the layer talking to
the network. Or consider
https://wsunit.dev.java.net/.
Ah, looks interesting. I've also heard of tools like SOAPUI and the likes which can be used for functional testing. Has anyone here had any success with such tools?
Thanks for all the answers and apologies for the ambiguous explanation; English isn't my first language.
-sasuke