How to write a test for GWT servlet? - unit-testing

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);
}
}

Related

Web Unit Tests not finding Url

I am using aspnetboilerplate 5.1.0.
In the ProjectName.Web.Tests I have run into a situation that I cannot solve.
I have set up web tests for my controller using [Fact] or [Theory].
When I attempt to run the tests using GetResponseAsString(string url, HttpStatusCode expectedStatusCode = HttpStatusCode.OK) found in the webtestbase class. All the tests fail.
Here is an example of my Test:
[Fact]
public async Task Index_Test()
{
//Act
var response = await GetResponseAsStringAsync(
GetUrl<HomeController>(nameof(HomeController.Index))
);
//Assert
response.ShouldNotBeNullOrEmpty();
}
The Tests all fail on this:
Message:
Shouldly.ShouldAssertException : response.StatusCode
should be
HttpStatusCode.OK
but was
HttpStatusCode.NotFound
I have other aspnetboilerplate projects in version 3.8.3 and 4.2.1 and the web tests work just fine. So I'm not sure why the server is not able to find the action methods on my controllers.
The service tests found in the ProjectName.Tests project run just fine.
I found the culprit. The problem I was experiencing was due to attempting to copy a project for web unit tests from one of the aspnetboilerplate project template repositories and updating all of the references and class names to match the names and namespaces in the destination VS solution.
I submitted a similar question on the aspnetboilerplate github account.
https://github.com/aspnetboilerplate/aspnetboilerplate/issues/5463.
Ultimately, here is what happened.
After going through the same process with a newer project. I found that In the
class file that would by default be named AbpProjectNameWebTestBase.cs in the method
protected override IWebHostBuilder CreateWebHostBuilder()
{
return base
.CreateWebHostBuilder()
.UseContentRoot(ContentRootFolder.Value)
.UseSetting(WebHostDefaults.ApplicationKey, typeof(AbpProjectNameWebModule).Assembly.FullName);
}
I mistakenly replaced AbpProjectNameWebModule with AbpProjectNameTestModule instead of AbpProjectNameWebMvcModule. This was trying to use the Application Service Unit test project as the web project. Therefore it could not find any of the referenced URI's and therefore returned httpStatusCode.NotFound.
After fixing this reference. I started getting exceptions that pertained to the public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) method.
These were things like adding app.UseAuthentication() and app.UseAuthorization() as well as needing to add a Middleware to provide a ClaimsIdentity and ClaimsPrincipal for the context.User (i.e. app.UserMiddleware<TestAuthenticationMiddleware>())
Now, I am able to get my web unit tests to run as I had in previous versions.

How do I perform unit tests involving redis, socket.io, and nodejs/express?

I am currently running into problems attempting to create unit tests that involve the interaction of socket.io, redis, and express. I'm looking for strategies on how to best mock these interactions. For example, I am using socket.io-client to mock the connection/behavior of socket.io to my express server but then when I add a test to check if redis is storing the proper information from socket.io I find myself needing to also mock socket.io in the redis unit test which in turn means I need to mock the express server. This leads to the point where it seems like I'm rewriting another server just to unit test the actual server I am trying to test.
Has anyone had to do this before? If so could you point me to resources (google/stack overflow are slim in results)?
What part of the application are you trying to test?
One way is encapsulating the socket connection in a socket.service.js file.
const socketIO = require('socket.io');
class SocketService {
constructor(server) {
this.socket = socketIO(server);
}
initialize() {
this.socket.on('connection', socket => {
console.log('connected')
socket.on('disconnect', () => {
console.log('disconnected')
});
socket.on('register', registerHandler);
socket.on('update', updateHandler);
});
}
}
Your unit test could be that it registers agains a mock server, and that it calls the initialize method.
If you are trying to test all of them working together, then you are talking about integration and e2e testing.

Best API / lib to unit test Jersey Restful Web Services?

What is the best library / API to unit test Jersey based Restful Web Services? Some APIs like JerseyTest seem outdated (had conflicts when using them in my pom) and also seem to be depending on a particular container, such as Glassfish or Grizzly... I am deploying my Jersey based Restful Web Services as a war file into Tomcat 7. Is there a way to use a testing framework which has an embedded web server or in-memory solution? Thanks again.
There are couple of frameworks that I am aware of atleast :
REST-EASY : http://www.hascode.com/2011/09/rest-assured-vs-jersey-test-framework-testing-your-restful-web-services/
Jersey Test Framework : https://jersey.java.net/documentation/1.17/test-framework.html
Jersey test Framework is easier to use.
I'm using rest-assured for many of my projects as it offers a highly specialized dsl to write your tests and once you've grown custom to the notation, writing tests is done really quick.
A variety of examples can be found on the project website but for a quick preview - a sample test could look like this snippet:
expect()
.statusCode(200)
.body("user.id", equalTo(1))
.when()
.given()
.contentType(ContentType.JSON)
.get("http://test/rest");
As my blog was quoted by Balaji, I'd like to add that there is this article of mine with more examples for the rest-assured framework and also a downloadable REST-server for testing the examples.
A test example with jersey-test could look like this example taken from the project's documentation:
public class SimpleTest extends JerseyTest {
#Path("hello")
public static class HelloResource {
#GET
public String getHello() {
return "Hello World!";
}
}
#Override
protected Application configure() {
return new ResourceConfig(HelloResource.class);
}
#Test
public void test() {
final String hello = target("hello").request().get(String.class);
assertEquals("Hello World!", hello);
}
}

How to test GWT/GWTP project?

I am currently building a web application using GWT, GWTP.
And I have some questions about testings:
Is there a Lint-like tool for GWTP or GWT?
How to test presenters? (GWTP with Mockito)
How to test views?
Thanks.
Presenters can be easily unit-tested using Jukito. Here's a quick example of a Presenter being tested using Jukito.
#RunWith(JukitoRunner.class)
public class ShowCommentsPresenterTest {
#Inject
private ShowCommentsPresenter showCommentsPresenter;
#Inject
private PlaceManager placeManager;
#Test
public void onReset_PlaceRequestHasNoShowId_ShouldHideView() {
//given
when(placeManager.getCurrentPlaceRequest()).thenReturn(new PlaceRequest());
//when
showCommentsPresenter.onReset();
//then
verify(showCommentsPresenter.getView()).hide();
}
#Test
public void onReset_PlaceRequestHasAShowId_ShouldDisplayView() {
//given
String someShowId = "12345";
when(placeManager.getCurrentPlaceRequest()).thenReturn(new PlaceRequest()
.with(ParameterTokens.getShowId(), someShowId));
//when
showCommentsPresenter.onReset();
//then
verify(showCommentsPresenter.getView()).display();
}
}
In GWTP's philosophy, Views should not be unit-tested directly. Using a dumb View that is a slave to the Presenter, most of the logic can be tested through unit tests on the Presenters. Tools like Selenium are a better fit for testing UI interactivity.
Google put out a great article about using different testing methodologies with GWT. Definitely check it out. Personally, I use JUnit when I'm testing back-end stuff like business logic, and Selenium for testing the UI and application as a whole from the browser's perspective.

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.