Scalatra Servlet init() during test (Jetty ServletTester) - unit-testing

I am testing a Scalatra servlet that does some important initialization in its init(context: ServletContext) method.
During tests (with ScalatraSuite) that init is not executed.
How should I do my important initialization when I am testing?
That Scalatra testing page (section "Testing FAQ") does not reveal that.
Extra Info:
The "Testing FAQ" section states
scalatra-test is built on Jetty's [ServletTester][3]
but I also could not extract any information from the internet on how to run the init if I were coding in java.

You can use the servletContextHandler for those things in a test.
You can set initParameters with servletContextHandler.setInitParameter("the.param", "the.value")
I'll update the docs so they won't say that the testing support is added through jetty tester.
In fact it uses an embedded jetty server so the init method should get called.

Related

How to unit test HandleEventAsync(ProcessEventArgs args) in Azure.Messaging.EventHub library

We are migrating to Azure.Messaging.EventHubs.Processor v5.6.0 library from Microsoft.Azure.EventHubs.Processor v4.1.0. I m using await messageHandler.HandleEventAsync(args); where args is of ProcessEventArgs type. Most of our business logic that I want to unit test is based on EventData which is a property of ProcessEventArgs. Event data has Readonly dictionary of systemProperties and other properties. The public constructor of EventData does not let us specify the systemProperties or any other property other than EventData body.
Both ProcessEventArgs and EventBody do not have mockable interfaces. In such case can you please advise on how can we unit test the code using ProcessEventArgs?
.NET Version: .Net core app 3.1
NuGet package version : Azure.Messaging.EventHubs.Processor v5.6.0, Microsoft.NET.Test.Sdk v16.6.1
The recommended approach for testing your handlers is to call them directly, as you're attempting to do. The constructor for each of the event argument types is public. (example: ProcessEventArgs).
For the PartitionContext, broker-owned properties on EventData, and other model types without a public constructor, the EventHubsModelFactory allows you to create them for use in mocking/testing scenarios.
This article offers more information on the philosophy and approach the Azure SDK takes for supporting unit testing. For Event Hubs specifically, we're currently working on extending our samples to include a set of direct examples for core scenarios such as yours.

Jetty Server not Working for War with JSPs

I am trying to create a simple jetty server/container that will take a war file and deploy. This is not embedded jetty with spring-boot.
Here is my build.gradle dependencies:
dependencies {
def jettyVersion = "9.4.34.v20201102"
implementation "org.eclipse.jetty:jetty-server:$jettyVersion"
implementation "org.eclipse.jetty:jetty-security:$jettyVersion"
implementation "org.eclipse.jetty:jetty-servlet:$jettyVersion"
implementation "org.eclipse.jetty:jetty-webapp:$jettyVersion"
implementation "org.eclipse.jetty:jetty-annotations:$jettyVersion"
implementation "org.eclipse.jetty:jetty-jmx:$jettyVersion"
}
Here is my main class:
public static void main(String[] args) throws Exception {
Server server = new Server(8080);
MBeanContainer mbContainer = new MBeanContainer(getPlatformMBeanServer());
server.addBean(mbContainer);
WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/");
webapp.setWar(warFile()); // LOGIC TO UPLOAD WAR FILE
webapp.setExtractWAR(true);
Configuration.ClassList classList = Configuration.ClassList.setServerDefault(server);
classList.addBefore("org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
"org.eclipse.jetty.annotations.AnnotationConfiguration");
webapp.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
".*/[^/]*servlet-api-[^/]*\\.jar$|.*/javax.servlet.jsp.jstl-.*\\.jar$|.*/[^/]*taglibs.*\\.jar$");
server.setHandler(webapp);
server.start();
server.dumpStdErr();
server.join();
}
However, when I try to go to the app (http://localhost:8080/index), I keep getting the following error message:
URI: /index
STATUS: 500
MESSAGE: JSP support not configured
SERVLET: jsp
There is only one line of error message in the console:
2020-12-11 09:49:51.563:INFO:oejshC.ROOT:qtp2025864991-33: No JSP support. Check that JSP jars are in lib/jsp and that the JSP option has been specified to start.jar
What JSP Jars that it is referring to? I am at a loss as to what dependencies I need to add to make it work for JSPs.
Thx.
You will have to add apache-jsp so that your server will support jsps. If your web app uses jstl, you should also add apache-jstl.
For WebAppContext usage (which is a bit easier to setup than ServletContextHandler usage) you'll need the following artifacts ...
https://search.maven.org/artifact/org.eclipse.jetty/apache-jsp (for the Jetty specific JettyJspServlet which extends from the Jasper JspServlet)
https://search.maven.org/artifact/org.eclipse.jetty/apache-jstl (to support Taglibs custom and standard)
Make sure your org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern can reference the apache-jsp artifact properly, otherwise the internal javax.servlet.ServletContextInitializer will not load properly.
If nothing happens by simply adding those artifacts, you'll need to verify your default descriptor setup on your WebAppContext.setDefaultsDescriptor(String) to ensure that you pass in a resource reference (path or uri) to the Jetty default descriptor XML.
https://github.com/eclipse/jetty.project/blob/jetty-9.4.35.v20201120/jetty-webapp/src/main/config/etc/webdefault.xml
Enabling JSP support in embedded mode can be quite tricky if you use the ServletContextHandler instead of the WebAppContext.
If you ever decide to use the ServletContextHandler instead of a WebAppContext (to have a single fat/uber jar, to speed up load/deploy time, to ease unit testing, etc...), then check out the Jetty maintained example project at ...
https://github.com/jetty-project/embedded-jetty-jsp

How to bring SOAP capability to payara/micro in EJB project

I have an EJB project providing webservices (both SOAP and REST) running inside a container with payara/micro as base image, since payara/micro does not come with JAXWS(SOAP support) feature out of the box, however, by adding
cxf-rt-frontend-jaxws
and
cxf-rt-transports-http
as dependencies into the project as well as following this tutorial and put the following code instead:
#Override
public void loadBus(ServletConfig servletConfig) {
super.loadBus(servletConfig);
Bus bus = getBus();
BusFactory.setDefaultBus(bus);
Endpoint.publish("/MySoapService", new ASoapService());
}
I was able to make the SOAP interface almost available (wsdl information is publicly available already), and
http://localhost:8080/<my project name>/services
event listed out the available services as well their available methods and endpoints/WSDL/Target namespace information.
But when trying to access the SOAP service via SOAP client, I got on the server side errors with the following line of info:
...
Caused by: java.lang.NullPointerException: null
at com.example.ASoapService.getXxx
...
Where
ASoapService
Is Actually an EJB. So I tried instead to replace the above code with the following:
#EJB
ASoapService aSoapService
...
Endpoint.publish("/MySoapService", aSoapService);
During startup of container, I got
Caused by: javax.naming.NameNotFoundException: com.example.ASoapServiceF#com.example.ASoapService not found
By checking the logs, I found a possible reason:
When SOAP part starts up with the following code
Endpoint.publish("/MySoapService", aSoapService);
The EJB Container is not yet ready and thus the lookup of
ASoapService
failed, is such assumption correct? Because normally you should see something like:
[2018-02-02T14:43:57.821+0000] [] [INFO] [AS-EJB-00054] [javax.enterprise.ejb.container] [tid: _ThreadID=1 _ThreadName=main] [timeMillis: 1517582637821] [levelValue: 800] Portable JNDI names for EJB ASoapService: [java:global/<my project name>/ASoapService, java:global/<my project name>/ASoapService!com.example.ASoapService]
during start up, which is not the case for my situation.
I am relatively new to EJB and Glassfish world, can I somehow force EJB container to start first? Or does it actually have anything to do with the starting sequence? How to combine the two together?
Thanks in advance.
You shouldn't be trying to force EJB container to start. Instead, try one of the following:
instead of #EJB ASoapService aSoapService to inject the EJB try #Inject
ASoapService aSoapService - #Inject should wait for the dependencies therefore wait until the EJB is available
run the method Endpoint.publish from an object which is initialized after EJB container is ready, either from a startup singleton EJB or when CDI application scope is initialized: https://rmannibucau.wordpress.com/2015/03/10/cdi-and-startup/

How to write a test for GWT servlet?

I have an GWT application, with few servlets on the server side. I would like to test those servlets (without the need to make GUI tests with Selenium, or any other web-based framework). Or in other words I want the test to simulate the client side of GWT.
The natural challenges with testing the servlets are:
Starting the webserver,
Simulation of client,
Servlets return immediately, passing the value to AsyncCallback object.
So far, I've been able to figure out (although this is still not tested), that:
1. I can start the container by extending GWTTestCase
3. I have found a google doc about asynchronous testing, so it is possible to wait for the async callback. Google docs are also mentioning this:
Server side testing
The tests described above are intended to assist with testing client side code. The test case wrapper GWTTestCase will launch either a development mode session or a web browser to test the generated JavaScript. On the other hand, server side code runs as native Java in a JVM without being translated to JavaScript, so it is not necessary to run tests of server side code using GWTTestCase as the base class for your tests. Instead, use JUnit's TestCase and other related classes directly when writing tests for your application's server side code. That said, you may want both GWTTestCase and TestCase coverage of code that will be used on both the client and the server.
But there are no examples or more in-depth explanation how to achieve this.
I haven't figured out how to simulate the client... Any ideas how can I do that?
Or, if this is not the way to do this, is there any other way? I would prefer to use native GWT classes, not not some 3rd party frameworks for testing the servlets.
Thanks!
How about using an embedded Jetty instance... The Jetty server is inculded in the GWT SDK anyway. So just include the gwt-dev.jar in your project and there you go for the server-side. Emulating the client-side is a whole different story. The problem is the JavaScript to Java serialization/deserialization which happens in GWT magic....
There is a project called gwt-syncproxy that can help here:
http://code.google.com/p/gwt-syncproxy/
In code this could look like this:
import junit.framework.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.ServletHolder;
import com.gdevelop.gwt.syncrpc.SyncProxy;
public class ServletTest {
private Server _server;
#BeforeClass
public void setUp() throws Exception {
_server = new Server(8080);
Context root = new Context(_server, "/", Context.SESSIONS);
root.addServlet(new ServletHolder(new MyServiceImpl()), "/servlet");
_server.start();
}
#Test
public void testMethod1() throws Exception {
MyService rpcService = (MyService) SyncProxy.newProxyInstance(MyService.class, "http://127.0.0.1:8080/servlet", "testMethod1");
String result = rpcService.testMethod1();
Assert.assertTrue(result != null);
}
}

Is there a usable standards-compliant (168/286) portlet testing framework? (especially one that works with Spring PortletMVC)

I've not seen anything in this area I would recommend to a client. If you've used Spring PortletMVC, how did you test it?
It's easy to test under the level of portlet code, and relatively easy to test on the client side through HtmlUnit, Selenium and the like, but I haven't seen anything that is a "Gray Box" test in the spirit of JSFUnit (which looks to me to be the way forward).
Apache's Pluto driver could theoretically be used to bootstrap a test harness. Has anyone tried this?
Any stub or data provider approaches?
Any approach to address two-phase processing concerns?
I don't know anything about portlets but here it goes.
There's portletUnit.
portletUnit is a testing framework
used to test JSR-168 portlets outside
portlet container just as servletUnit
is used to test servlets outside a
servlet container. The projected is
architected to map the functionally of
servletUnit onto portlets with
servletUnit itself providing the
foundation for portletUnit.
Some more related info could be found on his Project PortletUnit blog, including PortletUnit and Spring Portlet: Checking form validation errors.
When testing with portletUnit, it is
not obvious how to check if there were
any form errors. Fortunately, using
the render listener feature of
PortletRunner, there is a simple way
to check for validator errors.
There's also a blog article written by Nils-Helge Garli Hegvik in 2007 titled Testing Portlets with Jetty, Pluto and JWebUnit.
Remembering an excellent article from
Johannes Brodwall's blog about
integration testing with Jetty and
JWebUnit, I wanted to extend his
approach to use the embedded
jetty-pluto setup I have created. This
turned out to be to be quite easy.
Finally, Spring Framework documentation 10.2 Unit testing.
The
org.springframework.mock.web.portlet
package contains a set of Portlet API
mock objects, targeted at usage with
Spring's Portlet MVC framework.
[...] The org.springframework.test.web
package contains ModelAndViewAssert,
which can be used in combination with
any testing framework (e.g., JUnit 4+,
TestNG, etc.) for unit tests dealing
with Spring MVC ModelAndView objects.
[...] To test your Spring MVC Controllers, use
ModelAndViewAssert combined with
MockHttpServletRequest,
MockHttpSession, etc. from the
org.springframework.mock.web package.
Here's a related article written by John Ferguson Smart titled
Unit testing your Spring-MVC applications.
One of the great things about this
framework is how testable it is. In
Spring-MVC, any custom validators (for
field and form validation) and
property editors (for converting text
fields to specific Java types) are
dead-easy to test - you can just test
them as if they where isolated POJOs.
Spring-MVC also comes with a full set
of mock objects that you can use (with
a bit of practice) to test your
controllers to your heart's content.
For example, you can use classes like
MockHttpServletRequest and
MockHttpServletResponse to simulate
your HTTP request and response
objects. This is also made easier by
the fact that Controllers can be
instanciated as normal Java classes.
For example, imagine you are testing a
controller class for a page that
updates a client details record. You
could do this very simply as follows:
public class UpdateClientTest {
//
// Prepare your request
//
request.setMethod("POST");
request.setParameter("id", "100");
request.setParameter("firstName", "Jane");
request.setParameter("lastName", "Doe");
//
// Invoke the controller
//
controller = new ChoosePeriodController();
ModelAndView mav = controller.handleRequest(request, response);
//
// Inject any service objects you need
//
controller.setClientService(clientService);
...
//
// Inspect the results
//
assert mav != null;
assertEquals("displayClient",mav.getViewName());
Client client = (Client) mav.getModel().get("client");
assertEquals("Jane",client.getFirstName());
assertEquals("Doe",client.getLastName());
...
}
...
Checkout spring-test-portlet-mvc (https://github.com/markusf/spring-test-portlet-mvc), which exposes the features of MockMvc to the Portal context and lets you integration test your Spring Portlets easily.