This means what we really need is a context.xml file and a web.xml file, which are local source files for our project, and which get copied into and deployed with our WAR files and also
Trang 1In addition to the convenience that running the shell from a standard build provides, you also have all of the power of Maven at your disposal The mvncleaninstall com-mand will compile and bundle your project into a WAR artifact that can be deployed
to any JEE servlet container You can also package your project into a module by ply issuing the command mvn clean jar:jar (presuming you have included the source in the POM as discussed) You can run tests, including those based on GwtTest-Case (which we’ll cover in detail in the next chapter) by using mvncleantest
The behavior of most of the GWT-Maven goals should be fairly obvious The fit of Maven, and these goals, is that once you have a configuration in place, you can use, change, and share your build easily and get consistent results Another reason for using the GWT-Maven plugin, beyond the general convenience for GWT tasks it pro-vides, is the way it helps to manage and merge the WAR file deployment descriptor, web.xml This file is used in hosted mode with the embedded Tomcat server GWTincludes, and in web mode when you deploy your application as a WAR file Because of this dual use, there are a few configuration overlap points and divergences that have
bene-to be dealt with
We first discussed Tomcat Lite, the embedded Apache Tomcat instance included in GWT, in chapter 3 There we discussed the issues surrounding the maintenance of multiple configuration files—one for the hosted mode and one for the web mode—and how to manage those configuration files so that your projects can make use of service-side features provided by the JEE container
Tomcat Lite maintains its own set of context.xml (ROOT.xml in GWT terms) and web.xml configuration files Obviously, the ideal deployment process would need to
work both in hosted mode terms and in terms of creating a WAR file This means what
we really need is a context.xml file and a web.xml file, which are local source files for our project, and which get copied into and deployed with our WAR files and also are used in hosted mode
Creating an automated build process that allows the inclusion of project-local configuration files (context.xml and web.xml) that are used both for creating WAR
files and for automatically configuring Tomcat Lite has several advantages First, you
can maintain configuration information in one place, rather than in several ond, you can use common JEE container-managed resources, such as servlet filters, security realms, and data sources in hosted mode Third, if you import any module that includes servlet declarations, they are automatically available to your module with-out your having to just know about them and manually configure them (This third point, and the fact that GWT testing, something we will discuss in the next chapter, needs the embedded Tomcat, are the main reasons not to abandon the embedded instance altogether.)
Sec-TIP You may recall from chapter 3 that you do not have to use the embedded Tomcat instance supplied with GWT Instead, you can use the -noserver
Trang 2option and configure an external JEE container instance on your own If you use -noserver, and you plan to share your module with others, you need to include instructions for any server-side resources required.
To automate the process of handling this configuration, you have to be aware of the various files involved, and you need to have a process in place that automatically con-figures resources based on the context—whether hosted mode or WAR
deploy-The key is that the configuration file is part of the source, and is copied into the
distri-bution at build time
You can extend this concept to manipulate the Tomcat Lite configuration files based on the same project-local configuration data That is to say, you can use the manipulation and copying of files that a build process provides not only to create a distribution artifact (such as copying web.xml to where it belongs for a WAR file), but also to configure the embedded GWT Tomcat instance
DISCUSSION
In order to manage the Tomcat configuration for both the GWT-embedded Tomcat instance and for a deployable WAR file, we’ll need to manipulate and merge several source files We’ll use the deployment descriptor web.xml file, the Tomcat-specific configuration context.xml file, and the GWT module file
Listing 7.5 shows a sample MyProject web.xml file—this is meant to represent the web.xml local to your application This file contains no references to GWT service serv-lets (because we’re going to inject those based on information from the module), but
it may certainly contain other resources such as servlet filters, non-GWT servlets, base references, and so on
data-<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
Trang 3interesting, like log requests</description>
Listing 7.5 shows a fairly standard web.xml file, and that’s good That’s what we want
in terms of the source file Next, listing 7.6 shows the embedded GWT Tomcat included ROOT/WEB-INF/web.xml file
The only notable thing about the standard Tomcat Lite web.xml file, shown in listing 7.6,
is that it has a servlet entry for GWTShellServlet b In order to use something like our own filter from listing 7.5 within hosted mode, we basically need a combination of these files, as is shown in listing 7.7
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.
//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Sample Server</display-name>
Listing 7.6 The base GWT web.xml in tomcat/webapps/ROOT/WEB-INF
Listing 7.7 The merged GWT hosted mode
Include GWTShellServlet
b
Trang 4<filter-name>MyFilter</filter-name>
<description>This is a filter that does something
interesting, like log requests</description>
<filter-class>gwtip.module.sample.server.MyServletFilter</filter-class> </filter>
c This will ensure that our filter is there when our application runs in the shell This combination provides our hosted mode support and enables us to maintain our own configuration in that environment But, that’s the only environment where this file will work; it won’t work in web mode So, we have one more web.xml resource
we need to deal with We need a deployment-specific web.xml file for our WAR file that includes all of our GWT service servlet entries Listing 7.8 displays this final web.xml incarnation—the one that needs to go in our WAR file for deployment
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
<description>This is a filter that does something
interesting, like log requests</description>
c
Include ServletFilter again
b
Trang 5project-in a deployed WAR file; rather, we must have these explicit servlet entries We can get the servlet entries for the deployment-time web.xml file by inspecting our GWT mod-ule file (and all of those in the <inherits> chain) and including <servlet> and
<servlet-mapping> entries for eachservletdefined there
At this point, we’re dealing with four web.xml files, which is admittedly not an ideal situation Additionally, if we wanted to configure something outside of the stan-dard web.xml, such as a context-managed DataSource reference for use in hosted mode, we would have to include our own application-local context.xml file as well
Then we would need to apply that file to Tomcat Lite, too This source file would be
placed in our application at src/main/webapp/META-INF/context.xml (in similar fashion to an src/main/webapp/WEB-INF/web.xml file) Then, before the embedded Tomcat instance is invoked, we would need to replace the GWT Tomcat Lite file, tom-cat/conf/gwt/localhost/ROOT.xml, with our own (renamed to ROOT.xml)
You can manage this process manually by maintaining multiple web.xml files (one for hosted mode, one for deployment) and a context.xml file, and then overwriting the Tomcat Lite configuration as needed, but this is not very convenient Or you can elect to go the -noserver path and not even try to configure the Tomcat Lite instance This approach is very powerful and helpful, but it really just shifts the configuration problem rather than solving it What we have chosen to do is to automate the manage-ment of this process through the GWT-Maven plugin This is what the mergewebxmlgoal mentioned in table 7.3 does
Using GWT-Maven, you maintain only two files These are the same two files you maintain for any standard JEE servlet-based application using Tomcat, a project-local
Notice that <servlet>
element is generated
c
Trang 6web.xml file and a project-local context.xml file The plugin does the merge for you The GWT-Maven plugin can configure Tomcat Lite for hosted mode, can manage the required hosted mode classpath, and will also configure the correct web.xml for deployment If you do not wish to use Maven, you could use the same approach with other build tools as well The main point is that source files can be used to both con-figure the embedded GWT Tomcat instance and create what is needed for a deploy-able WAR file—and all of this can be automated
This is admittedly an involved process, but once it’s automated it’s a huge help With an automated build that manages the process, you can control the configuration
in the source, just as with standard non-GWT Java projects Also, you can share GWTprojects that involve not only RPC but other server-side resources and concepts, such
as filters and data sources, without requiring others to manually set up the required configuration for hosted mode
Configuring a GWT project for build and deployment can be confusing at first, but things on the inside are really not much different from a combined standard web application and a JEE servlet-based application The compounding factor is that you basically have two environments to build for: hosted mode and web mode Even though you aren’t deploying things for hosted mode, you still have to get the configu-ration correct so that the development shell is productive And when deployment time does arrive, you need the same configuration to work in an external setting
In this chapter we addressed building and packaging GWT modules, and building and deploying GWT-based applications Along the way, we also brought the Ant and Maven automated build tools into the fold These tools can be used to manage config-uration elements and direct the build process, even down to the configuration of the GWT-embedded Tomcat instance In the next chapter, we’ll extend the concepts behind the automated build to include testing and benchmarking Then we’ll bring all of those components together, again with Maven, to build and test a GWT project using a continuous integration server
Trang 7Testing and Continuous Integration
A test that reveals a bug has succeeded, not failed
—Boris Beizer
Completing your code and turning out a quality application are not often mous nor simultaneous Beyond the syntax, the compiler, and the resulting bits, a quality application is usually the result of careful design, adequate testing, and proper component integration These fundamental concepts can be applied to all software projects, but putting them to work with GWT is a bit different than in other environments
In this chapter, we’re going to follow up on some of the tasks related to ing, packaging, and deploying that we addressed in the last chapter, with a focus
build-This chapter covers
■ Understanding and implementing GWT tests
■ Exploring advanced testing techniques, remote
Trang 8on testing and automating builds Along with testing, we’ll also touch on ing in a GWT context Once we have all the pieces in place, we’ll work through a sam-ple project that utilizes Maven and a continuous integration (CI) server, in order to take full advantage of the complete process All of these concepts go hand in hand because testing and metrics should ideally be part of an automated build process that’s CI managed
The concepts of testing, benchmarking, and continuous integration are fairly well accepted tenets in any good software development practice, regardless of language or technology Even though we cannot hope to cover these broad subjects comprehen-sively in a single chapter, we’ll go into some detail on the general principles, and we’ll focus on getting these things working with a GWT project
To make testing possible, GWT provides several testing tools and related supporting classes, which allow you to run tests against Java bytecode in hosted mode or against JavaScript in web mode These are the same concepts that apply during development when using the GWT shell When using web mode testing, a special JavaScript translat-able JUnit support layer is automatically invoked by the toolkit
Before we begin looking at GWT testing, we first need to narrow down what the testing support is intended to address and what it is not We’ll also look at some of the common issues concerning testing and touch on the testing process Once we have that background, we’ll work through several GWTTestCase-derived tests to hash out the details After we have looked at testing GWT client-side code, we’ll also briefly cover testing server-side code, and entire applications, outside of the toolkit
Knowing the what, how, and where of testing will enable you to create better tests, which in turn will help you better understand your code and the toolkit, which will result in better applications
8.1.1 Knowing what to test
The testing support provided by GWT is intended for testing your GWT client-side code, but not your UI This may sound contradictory, and possibly even controversial, but it’s important to understand it nonetheless Non-UI client-side code includes your client-side model (logic and data) and any client-side controller you may be using, but not the view In GWT unit testing, you should test asynchronous application-related event handling, client model beans, client-side logic, and the client side of GWTRPC You should not worry about testing browser-based events (button clicks, mouse move-ments, and the like) or panel layout
You can, with some special test and event-related helper code, test UI concepts within GWT unit tests, but you should not be very concerned about doing so When you click on a GWT Button, the ClickListener that responds is part of the toolkit itself, not your code If that ClickListener contains non-UI logic, in the onClick()
method for example, you might be tempted to try to test the button in order to exercise
Trang 9your code Yet, an often cleaner and easier practice is to move the logic from the UIwidget into a client-side model, and invoke it through a client-side controller (We dis-cussed these concepts in chapters 2 and 4, and have used them in the examples throughout the book; we’ll do the same with the code later in this chapter.)
In other words, design your application so that you can test logic and events through a controller method, rather than through the GWTUI With such a design, you can test the controller directly without needing to worry about a Button There are many benefits to the separation of responsibilities MVC provides, and making unit testing easier and more focused, especially in the context of a UI toolkit, is a signifi-cant one
We also need to stress that we’re referring to GWT unit tests in this chapter You should still test the overall UI in integration or acceptance testing with tools outside of GWT Also, when testing non-GWT specific code, such as server-side code, you do not need GWT support In those cases, you should use standard JUnit or similar testing mechanisms We’ll come back to this in section 8.1.5 when we cover testing from out-side the GWT perspective GWT tests have a specific scope, translatable client-side logic and data, and RPC marshaling and interaction Other testing mechanisms can pick up where these tests leave off
Deciding what to test using the GWT testing support involves being familiar with all the moving parts Knowing a bit about what is happening behind the scenes will help you utilize and troubleshoot GWT tests
8.1.2 How GWT testing works
GWTTestCase is where it all begins When you write a test case in GWT, you extend TestCase, which itself extends the standard JUnit TestCase GWTTestCase requires you to tell the test what module it will be using via the getModuleName() method and includes several other very simple methods that allow the adding and removing of
GWT-checkpoints (these are used to simulate something resembling a stack trace in web
mode, which otherwise would not be possible) GWTTestCase also invokes the JUnit shell, the all-around traffic cop of the GWT testing system
The JUnit shell is an extension of the standard GWT shell, with test-specific ities It is basically a harness that controls all the GWT magic for tests One special aspect of the JUnit shell is that it’s invoked automatically for you, so you can’t pass arguments directly to it the way you’d do with the standard GWT shell The JUnit shell supports many of the same options as the GWT shell, but you need to use the
capabil Dgwt.args system property when invoking a test runner to route arguments to it We’ll see how to use this technique in several examples later in this chapter The JUnit shell also forces the inheritance of a special GWTJUnit module into each test module that passes through it, and it caches module definitions
The GWTJUnit module does several important things First, when the module inition loader encounters classes that are of GWTTestCase type, it defines the genera-tor used to create JUnit test case stubs, as follows:
Trang 10JUnit system
The second thing the JUnit module does is to set the servlet path in the module definition to the special JUnitHost class This class acts as the server-side endpoint for GWTJUnit tests
All the moving parts—GWTTestCase, JUnitShell, the GWT JUnit module, and
JUnitHost—operate in a loop with a message queue, as outlined in figure 8.1 For this reason, tests are not inline, and TimeoutExceptions can sometimes occur In these cases, the testing harness may not always know exactly why your test didn’t complete We’ll elaborate more on this in the next section, when we cover common testing issues Although there are several components involved in GWT testing, and having an overall understanding of the process helps, don’t worry if it seems daunting at first You don’t have to dig into the details in most cases, because the toolkit handles the complexity and translation for you With a few guidelines in mind, you can simply con-centrate on writing GWTTestCase-derived tests
However, it is helpful to be aware of some common pitfalls
GWTTestCase (web mode version)
Translatable JUnit support classes
Server classes
JUnitHostImpl JUnitMessageQueue
Figure 8.1 The high-level components in the GWT testing
Trang 11you understand them, but they are sometimes tricky to remember—especially if you have years of non-GWT testing habits The most common GWT testing issues that are apt to trip up traditional developers fall into three main areas: paths, TimeoutException, and test class initialization.
First, when dealing with paths, remember that GWT requires the source on the classpath for its compilation step, and this applies to testing and test sources, too This issue comes
into play for everything that passes through the GWT compiler A common error in GWT testing is to forget to add the test source itself to the classpath
You have to remember this step for every tool or testing process and add the source
to the classpath If you’re using Eclipse 3.x, for example, you can add the source to the User Entries section of the run configuration by clicking the Advanced button on the Classpath tab of the Run configuration window, as shown in figure 8.2 You have to
do this manually Eclipse, like most other Java tools, does not include the source in the run configuration by default
Along with the sources on the classpath, you also have to remember to include all translatable code in the GWT source path This includes test cases themselves The
Figure 8.2 Adding src and test source paths to the User Entries portion of the classpath,
Trang 12source path, as discussed in chapter 2, is defined in your module’s gwt.xml file and tells the GWT compiler where the sources are located If your test case is not in the default client source path package, you need to add the package it’s in (whatever you name it) to the configuration The GWT compiler performs a compilation step to translate your test classes into JavaScript, and if it cannot find your test classes, GWT-TestCase will throw a TimeoutException, which can be misleading.
The next common problem area is the TimeoutException in general The current generation of GWT testing support is, well, not speedy This is more than just an inconvenience The process is rather involved, and it can take a while if a lot of classes have to be translated or compiled by GWT, or both This can cause problems, because the JUnit shell will also throw a TimeoutException if it hasn’t seen a test method fire and contact the testing harness within 60 seconds If you have a problem with slow-ness and have double-checked that your classpath and source path are correct, you may want to create a test-specific module Such modules can reference fewer classes, leaving out the UI entirely, for example This allows the compiler to prune and opti-mize things specifically for the tests, which speeds things up and may eliminate a
TimeoutException problem (if the timeout is due to a large number of translatable classes being present)
In addition to being aware of the most common reasons that a TimeoutException
might crop up, you should also be aware that you should not try to use GWT-related classes during the initialization of a test case Specifically, the JUnit setUp() method, any static initializers, and the constructor of a test case are off limits for GWT-related instantiation This is because the GWT testing process serves a dual purpose GWT test-ing can be done in either hosted mode, using Java, or web mode, using JavaScript Because of the way the JUnit setUp() method is called in GWTTestCase, which hap-pens before things are passed off to the JUnit shell, you have to avoid doing GWT-specific tasks before your actual test case gets beyond setUp() If you do try to instan-tiate a GWT component before the setUp() method completes, “badness ensues,” as Scott Blum of the GWT team puts it This can be inconvenient, but it is also something you can work around once you’re aware of it
To recap, the most common testing problems people encounter with GWT are listed in table 8.1
Table 8.1 Common GWT testing issues and their solutions
Sources not on the
classpath
Test sources are required on the classpath If they are not present, tests will not be found and will not compile
As with non-test code, code that’s going to be passed through the GWT compiler has to be on the classpath, and this includes tests Include all test sources on the classpath.
Trang 13We’ve now covered the background and outlined some common problems, so let’s get
to some actual tests
8.1.4 Basic GWT tests
We’ll start looking at the simplest GWT tests and focus on getting dependencies and commands in order We’ll start small to prove the infrastructure is in place, and then move on If GWT testing is new to you, this is the place to stay focused Even though these are basic tests, GWT testing is a bit different from any other form of unit testing you may have previously done
If you have already done some GWT testing and are familiar with the basics, you may want to skip ahead to the next section, where we’ll look at more advanced concepts
USING JUNITCREATOR
GWT provides many useful utilities for developers Tools like ApplicationCreator,and ProjectCreator, which we covered in chapters 2 and 3, get a basic project outline
in place and enable you to create IDE- or Ant-related files respectively Along those same lines, GWT includes JUnitCreator for wiring up some initial GWT testing
TimeoutException will occur.
The default source path that GWT modules implicitly scan is client If you create tests outside that pack- age, such as in test, you must spec- ify your source path in the module file Include all test packages in the source path.
Tests throw
TimeoutException
The JUnit shell will timeout if it takes more than 60 seconds (the timeout currently defined in the code) for the test browser to contact the test server This can happen if you have a large code base and a lot of compilation is required before the test can run.
Create a test-specific module to cut down on involved classes, and cre- ate a simple initial test in your test case so that the first test completes quickly (without needing RPC)
GWT-specific code
out-side of test methods in
test case classes
If you use the JUnit setUp() method, a static initializer block, or a constructor to create GWT-specific components you’ll run into problems.
Keep your GWT-specific code in your test methods Do not use the setUp() method, static initializers,
or constructors for GWT code-related GWTTestCase purposes
Table 8.1 Common GWT testing issues and their solutions (continued)
Trang 14The most basic test scenario in GWT is a new Hello World project with a test that extends GWTTestCase Fortunately, GWT gives you both of these things right out of the box, through the ApplicationCreator tool we have used previously and JUnit-Creator, which is a similar tool for testing
We’ll create a new project using ApplicationCreator, and then create a test using
JUnitCreator This can be done as follows:
If you take a look at the test class JUnitCreator produces, you’ll see that it’s a bones class The only interesting thing about it is the fact that it extends GWTTestCase The command-line scripts ProjectCreator produces are where the real details are These scripts include the required dependencies in the classpath (including JUnit and GWT themselves, and the source and compiled classes for the project), and they pass the test to JUnitRunner For example, on the Mac platform, MyProjectTest-hosted,
bare-as generated by JUnitCreator, looks like this:
One last step is needed before the command-line script can be used and the test can
be run The test class has to be compiled with javac This can seem counterintuitive, but the test scripts will look for the compiled class in the bin directory by default, and
Trang 15will expect you to have taken care of the compilation step on your own (it’s not done for you) Normally you’d automatically get the bin output with an IDE, but you can also just compile things manually for this quick example as follows:
javac -d bin -cp "[JUNIT_JAR]:\
Time: 6.683
OK (1 test)
You’ll probably quickly outgrow JUnitCreator and graduate to creating your own tests and running them via a build tool, such as Maven (which we’ll use later in this chapter) Nevertheless, JUnitCreator can be a big initial help in terms of understand-ing the components involved
To further exercise our GWT testing muscles, we’re now going to step into a sample project that involves passing a model bean across the wire, and we’ll work on some related tests As we proceed, we’ll look more closely at several aspects of GWTTestCase-derived classes, and we’ll investigate asynchronous testing of an RPC service
TESTING A MODEL BEAN
In this section, and the next few, we’ll be using a sample project named GWTTestMe This is a very simple project that includes a model bean class for Person, a controller that invokes a single RPC service, and a simple GWTWidget for the view The project allows for Person objects to be added to, or removed from, a list, and the current ver-sion of the list is displayed to the user We can put this small GWT project through some testing, while remaining focused on the tests themselves We’ll only look at the relevant sections of the project code in the text, but the complete source for this proj-ect is available at the Manning website
The Person bean we’ll be using is a translatable client-side model object that we’ll serialize and send across the wire to the server using GWTRPC The service interface is shown in listing 8.1
public interface MyService extends RemoteService {
public void addOrUpdatePerson(Person p);
public void addOrUpdatePersonSlow(Person p);
public void removePerson(Person p);
/**
* @gwt.typeArgs <com.manning.gwtip.testme.client.model.Person>
Listing 8.1 The MyService service interface
Define special slow service method
b
Trang 16*/
public List listPeople();
}
The service interface in listing 8.1 performs some fairly common persistence tasks on
a model object We do have one unusual interface method definition though, the cial addOrUpdatePersonSlow() method, which will be used later to purposely time out
spe-an asynchronous test b What happens on the server side of these interface methods could be persistence via the JPA, a proxy call to a non-Java interface via SOAP, or any other type of mechanism to deal with the data
To put the Person object and GWT object serialization to the test, so to speak, we need to implement a few GWTTestCase classes The first of these is a simple test of the model object itself
public class GwtTestPerson extends GWTTestCase {
public String getModuleName() {
return "com.manning.gwtip.testme.TestMe";
}
//
public void testPersonEquals() {
Person p1 = new Person("first1", "last1");
Person p2 = new Person("first1", "last1");
Person p3 = new Person("first1", null);
Person p4 = new Person("first2", "last2");
You may say, “hey, I can test that without GWTTestCase,” and you’d be correct, but such a test would have several shortcomings Without GWTTestCase, you cannot test
Listing 8.2 Testing a Person model object with GWTTestCase
Extend GWTTestCase
b
Specify module name
c
Perform equality test
d
Trang 17that your classes—even simple beans—operate as you expect in the limited JRE ronment available to you with GWT Also, you cannot test the GWT translation to JavaScript for web mode, which means you cannot test what really happens at run-time Additionally, in order to work with GWT RPC, perform remote GWT testing across different browsers, or use GWT benchmarking, you need a GWTTestCase-derived test
Within our test class, the getModuleName() method is required to inform the JUnit shell which module needs to be run c Also, this test checks the equality of a Person
object d The equals() method we have implemented does not use the getClass()
method, as it normally might, because that’s not available in a GWT context This means we have a test that works differently because of the ultimate JavaScript nature
of this model object A normal Java object—one that we didn’t attempt to translate by using a GWTTestCase-derived test—would work fine with a getClass() call within it, but with GWT this reflection-based usage breaks down (getClass() is not allowed, as was explained in chapter 1) In this case, it’s not actually the test that’s different, but the fact that we’re using GWTTestCase at all, which brings along the GWT environ-ment, that makes the difference
To run this test, we need to invoke a JUnit TestRunner and pass it our Case-derived test with the required GWT and JUnit dependencies on the classpath, just
GWTTest-as the JUnitCreator scripts we saw in the previous section do There are many ways to get all these parts in order to run the test You can do it with a shell script, just like
JUnitCreator, or an IDE, but those can be difficult to manage and automate later Or, you can use a build tool that can invoke tests and handle the configuration for you, such as Ant or Maven
We recommend Maven and the GWT-Maven plugin, which we introduced in ter 7, and we’ll use it again in several sections later in this chapter when we discuss code coverage and continuous integration GWT-Maven can automatically configure
chap-GWTTestCase-derived tests to run The sample code for this chapter makes use of GWTMaven and includes the files required to run the GWTTestMe project using Maven
-TESTING GWT RPC
Now that you know what is required for a GWTTestCase-derived test, the basic approach for implementing such a test, and the purpose of using GWT test support, we’ll move on to testing GWTRPC This involves testing asynchronous operations
GWTTestCase class for just this purpose These methods, delayTestFinish() and
finishTest(), enable testing of asynchronous GWTRPC
Trang 18To demonstrate using the GWT’s asynchronous testing support, we’ll use a ler object to send a Person bean across the wire The test shown in listing 8.3 performs this function.
control-public class GwtTestMyService extends GWTTestCase {
private static final int TEST_DELAY_1 = 500;
private static final int TEST_DELAY_2 = 3050;
public String getModuleName() {
public void testAddOrUpdatePerson1() {
Person person = new Person("Angus", "Young");
public void propertyChange(PropertyChangeEvent e) {
List newPeople = (List) e.getNewValue();
public void testAddOrUpdatePerson2() {
Person person = new Person("Bon", "Scott");
PeopleModelData peopleData = new PeopleModelData();
Controller controller = new Controller(peopleData);
peopleData.addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e) {
List newPeople = (List) e.getNewValue();
b
Remember, no GWT in setUp()
g