So I managed to create a GWT-SpringMVC setup. Wasn't easy (not too many resources), but possible. I even autowired and stuff. It even works :)
However, I can't figure out how to make the GwtTestCase run. Obviously it needs the "server" to be up, and because I use Spring, it needs to pass through the dispatching servlet (no?). But I can't figure out how to connect the two. In production or hosted mode, I got the web.xml and the spring-servlet.xml to configure these things. What can I do for tests?
I thought of ignoring the web part and testing the service directly - but this will deny me the option to automatically tests that everything is "transferable".
(if you have an idea on how to do that, I might ditch the GWTTestCase altogether).
An alternative to GWTTestCase could be the gwt-test-utils framework, which provides a simple integration with Spring (see here for details)
Related
I wonder if there is any option to configure tomcat when using http4s server API. Tomcat builder allows to change some basic options, but besides those there is no much what can be set. Could I somehow provide a server.xml file? Or get access to tomcat instane?
Tomcat, AFAIR is a server running applications defined as WARs. That is: your app is not a server, your app is logic bound to functionalities provided by this external layer.
Http4s server talks to the external world directly, it manages requests lifecycle through FS2 streams, if you use it then you probably talk to DB through e.g. Doobie or some other Cats library, which also manages its own thread pools and transactions instead of relying on ThreadLocals and other JavaEE-like and JPA-like conventions.
Long story short: these models are incompatible.
You would have to rip-off 90% of Http4s to leave something that could be agnostic to implementation, and then wire it to Tomcat, but that would leave only, IDK, DSLs for building requests? And for that you'd have better chances to e.g. define things using Endpoints4s or Tapir and implementing interpreter which binds things to Tomcat.
But at that point there would be probably 0 benefits from using Tomcat or any other servlet container: in Java EE it is usually easy to monitor things because you have 1 thread per 1 ongoing request, and all DB connections and stuff is put into ThreadLocals as request-scoped things. Meanwhile virtually all IO monads use thread pools (separate for different boundaries) so your operation can span across several threads. All conventions that containers rely on to monitor things (which are quite inflexible performance-wise) go to hell.
Meanwhile Http4s has its own ways of tracking things (through middleware), similarly you can add instrumentation to DB queries. So things provided by servlet container are also available there, though it requires a bit of effort to configure them.
The bottom line is: if you are using Http4s, you don't need servlet container, and if you are using servlet container, then you don't have a nice integration with anything that is using any IO monad (scala.concurrent.Future, cats.effect.IO, monix.execution.Task, zio.ZIO, etc) as they aren't guaranteed to run whole operation in the same thread (invalidating a lot of assumptions made by certain Java frameworks).
GWT's servlet implementation has onBefore/onAfterDeserialization which would give me a hook with which to start and stop transactions without doing anything fancy, however those methods don't allow me to properly check for error conditions after the service method got invoked, I just have access to the serialized return value, not directly to any exception that might have been thrown, so deciding whether to roll back or not is not possible that way without rewriting parts the GWT servlet.
I was thinking about using aspectj's compile-time weaving. However, this does not work with Netbeans' compile-on-save feature because the module needs to be recompiled using the aspectj compiler.
How about LTW (load-time-weaving)? Is there any way (or example) to add LTW to the webapp container without using the Spring framework?
I was also thinking about using AOP based on Java dynamic proxies, ie. to put a proxy in front of the servlet. Again, the question arises how to tell the Jetty WebApp container to load the proxy instead of the original servlet.
Or is there any ready-to-use solution out there already?
I think you could overwrite a combination of
public String processCall(RPCRequest rpcRequest) from RemoteServiceServlet and RPC.invokeAndEncodeResponse to do what you want.
Not ideal, as you need to copy/paste a few lines of code, but they really are only a few.
I myself hit the same problems as I needed some customizations, and relevant methods didn't had the access modifier that I needed, so I ended up copy/pasting some portions.
I can't comment on the rest of your question, but I don't expect to find any ready-to-use solutions, as GWT-RPC doesn't seem to have any new fans out there; just people maintaining legacy systems. Therefore, I expect that you either don't find anything or find solutions that are no longer maintained.
We are working on some spikes using Fuse ESB (Camel,OSGi, blueprint) to deliver some components. We have an imposed architecture from our EAs which is: REST controller uses a route to call a CXF WS. This calls a local java class as a service to, for example, perform CRUD actions. These use JPA enabled DAO/entities. All seems a bit academic in design rather than real world but thats another story.
Question is about testing. Normally I would actually test this service tier using H2 to provide the DB, wiring the DAO, entityManager etc together with spring (I know some wouldn't do this but I do, bear with me). But we will use blueprint for fuse. How can I unit test this tier? Getting my tests to subclass CamelBlueprintTestSupport doesn’t work, this expects a route. Can’t use SpringJUnit4ClassRunner (though do have it working with this currently) as this wires with spring, when running in the container we will wire with blueprint.
So how do we unit test this? How do I instantiate this set of classes within a blueprint based unit test? Can we?
One aproach you may try is to use pax exam. It allows to run tests in a full OSGi environment. So you can install your real bundle test it in a black box fashion.
You can use pojosr which is what camel-test-blueprint is using: https://code.google.com/p/pojosr/
Though pojosr is not a full OSGi environment, so there will be some limitations what you can do.
For the camel-test-blueprint you may be able to override the method isUseRouteBuilder and return false, then it ought not to expect a route.
I'm currently developping a REST Web service with Spring MVC.
And I am struggling to find the best way to do integration tests on my WS.
First solution : using rest-assured
Advantage : fluent api, really easy to use with its cool DSL
Drawback : when i perform POST or PUT requests on my WS, the state of my database is modified, and next tests are corrupted.
Second solution : unit test the controllers and perform integration tests at the service level separately
Advantage : i can control the state of my database, using Spring Test Framework and perform rollback after each test
Disadvantage : i do not perform end-to-end integration tests anymore.
Question : how can i use rest-assured to do integration tests without modifying the state of my database ?
Thanks a lot.
Why don't you delete the rest assured doubles and redirects before every test and set them up fresh for the test?
RestClient.delete "#{RestAssured::Server.address}/redirects/all"
RestClient.delete "#{RestAssured::Server.address}/doubles/all"
Or alternatively you can use different doubles for the GET and POST/PUT calls to the rest assured and use the redirects in between these calls.
I am not sure, your request makes sense as you state it.
RestAssured is just a framework to support you with testing. You can also write unit tests, that do the equivalent of PUT and DELETE (basically the internal implementations), which then modify the database state.
Or you can only issue HEAD and GET requests with RestAssured and not modify the database state by this.
Both of the options will only test parts of the code path if you leave any updates out, so your issue is orthogonal to the selection of RestAssured or hand written unit tests.
Of course you can mock your backend away, but either the mocks are trivial and you don't gain any insight. Or they are complex and you will need separate tests to assure that the mock objects to what you think they are doing.
In order to perform integration tests on a REST Spring MVC Web Service, the SpringSource team has provided a new library called spring-test-mvc, which is now integrate to spring-test.
http://blog.springsource.org/2012/11/12/spring-framework-3-2-rc1-spring-mvc-test-framework/
For my special purpose, it is more adapted than Rest-Assured.
I have a server-code that's written in Python, and I have a client-code that's written with GWT. Now I want to run automation testing on the GWT against the data from the Python server.
From what I searched, people recommends using the Selenium, but I prefer to have a GWT-test that has more visibility into the client-code. That way I can verify the local database, and any data that are not exposed to the UI.
Also at this point I'm not too worried about the DOM aspect, layout, and the other UI stuff.
Is there anyway to make the GWTTest work with external server?
I've tried to search for the solution, or people with similar problem, but I couldn't find one. If this question has been asked previously, I apologize.
Thanks, KOkon.
You can use the GWTTest framework to incorporate testing some GWT components that call the server. But the tests won't be able to communicate directly with the server. If you need your tests to set up state on the server, I'm afraid you'll need to write special "for testing purposes only" RPC servers or servlets or similar to do it.
Having said that, I would (presumably like those who suggested Selenium) recommend three types of tests:
Unit tests for server components, and unit GWTTests for client components,
Integration tests for testing server code interaction with database, etc.
Selenium acceptance tests, which are "black box" - they don't have access to the innards of the GWT components.
What you could do is create a proxy servlet that gets started in the GWTTestCase embedded Jetty instance. That proxy could forward all calls to you real services in Python.