-
Notifications
You must be signed in to change notification settings - Fork 0
/
EJB.html
237 lines (197 loc) · 10.9 KB
/
EJB.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<meta http-equiv="imagetoolbar" content="no" />
<meta name="author" content="Christophe Bouthier" />
<meta name="copyright" content="copyright 2009 - INRIA" />
<meta name="keywords" content="Qualipso, qualipso factory, open-source, quality, service, development" />
<meta name="description" content="Documentation for the Qualiso factory - defining EJB service" />
<link rel="stylesheet" href="commons/css/style.css" type="text/css" />
<link rel="stylesheet" href="commons/css/lightbox.css" type="text/css" media="screen" />
<script type="text/javascript" src="commons/js/prototype.js"></script>
<script type="text/javascript" src="commons/js/scriptaculous.js?load=effects,builder"></script>
<script type="text/javascript" src="commons/js/lightbox.js"></script>
<title>Qualipso Factory - Tutorial - Part III</title>
</head>
<body id="www.qualipso.org">
<h1>Qualipso Factory</h1>
<div id="wrapper">
<div id="menu">
<div id="menu_all">
<ul>
<li><a href="install-env-service.html">Installation</a</li>
<li class="selected"><a href="create-new-service.html">Development</a></li>
</ul>
</div>
<div id="menu_global">
<h2>Tutorial map:</h2>
<ol>
<li><a href="create-new-service.html">Create a new service</a></li>
<li><a href="add-test.html">Add the test structure</a></li>
<li id="selected"><a href="EJB.html">Define the EJB service</a></li>
<li><a href="remote.html">Implements remote access</a></li>
<li><a href="factory.html">Qualipso Factory services</a></li>
</ol>
</div>
<div id="menu_local">
<h2>Steps:</h2>
<ul>
</ul>
</div>
</div>
<div id="content">
<h2>Defining the EJB Service</h2>
<div id="introduction">
<p>Now that the whole <a href="add-test.html">projects infrastructure</a> is ready for development, the real work can start, that is designing, implementing, and testing the new service. The goal of this tutorial page is to give the necessary instructions to fullfill those steps. The approach chosen is a test-driven approach: first implementing the functional tests, then the unit test, then the interface, and finally implementing the service. Concerning the implementation, only the basic EJB part will be done here, not the full service implementation. Indeed, a full real service needs to call Qualipso Factory services (after all, that's the whole goal of the game here), and the use of Qualispo Factory services will be done only in the last part of the tutorial. In the meantime, this page concentrate on the EJB part of the service.</p>
</div>
<div id="checklist">
<h3>Checklist</h3>
<p>Here is the checklist of everything that you will do on this level:</p>
<ul>
<li><a href="#FUNCTIONAL">Create the functional tests</a></li>
</ul>
</div>
<!-- Functional tests -->
<div class="step">
<h3><a name="FUNCTIONAL"></a>Step 1: Create the functional tests</h3>
<p>The functional tests correspond to user stories for the service, testing its whole functionality. That's why it's a good idea to start by creating those functional tests before even implementing the service: you create a running specification of your service, that will help you concentrate on the <em>usage</em> of your service (instead of loosing yourself in implementation details). Moreover, those tests provide you with a easily checkable achievement point: you have finished implementing the service <em>once and only once</em> all the functional tests are passing correctly.</p>
<p>The first thing to do is thus to define how the twitter service will be used, that is to create user stories. As this is just a tutorial and the goal is not to create a full usable service, simple user stories will be enough:</p>
<ul class="projects">
<li>a first user, <em>"Caleb"</em>, create a tweet about something; then a second user, <em>"Kurtzmann"</em>, gets the tweet from Caleb. The test should assert that Kurtzmann get the correct tweet from Caleb.</li>
<li>Kurtzmann create <em>two</em> tweets, and Caleb get the tweets from Kurtzmann. The test should assert that Caleb get the two tweets from Kurtzmann, and in the correct order.</li>
</ul>
<p>Let's translate that in a functionnal test. Functional tests are defined in the <em>"funkyfactory-service-twitter-ftests"</em> project.</p>
<ol>
<li>
In the <em>"funkyfactory-service-twitter-ftests"</em> project, open the <em>"TwitterServiceFunctionalTest.java"</em> file, in <em>src/test/java</em>. There should already be the declaration of an empty class called <em>"TwitterServiceFunctionalTest"</em>.
<pre><samp>public class TwitterServiceFunctionalTest {
}</samp></pre>
</li>
<li>
Create a first method, called <kbd>"testSingleTweet"</kbd>, that take no parameters and return <code>void</code>:
<pre><samp>public class TwitterServiceFunctionalTest {
<span class="new">public void testSingleTweet() {
}</span>
}</samp></pre>
</li>
<li>
To indicate to ejb3unit that this method is a test, add the <kbd>@Test</kbd> annotation to the method:
<pre><samp>public class TwitterServiceFunctionalTest {
<span class="new">@Test</span>
public void testSingleTweet() {
}
}</samp></pre>
(In fact, the <em>@Test</em> annotation is a JUnit annotation, not an ejb3unit annotation. But ejb3unit goal is precisely to bring JUnit functionalities for testing EJB. Thus the use of JUnit annotations.)
</li>
<li>
Now, you can implement the first user story in this method. Concentrating on the story itself and not on the implementation details, the story can be written like this:
<pre><samp>@Test
public void testSingleTweet() {
<span class="new">String tweetText = "1001 way to use cryptonite is a fabulous book.";
Caleb.login();
Caleb.getTweetService().tweet(tweetText);
Caleb.logout();
Kurtzmann.login();
Tweet[] tweets = Kurtzmann.getTweetService().getTweetsOf(Caleb.profile);
Kurtzmann.logout();
assertEquals("There should be only one tweet", 1, tweets.length);
assertNotNull("Caleb tweet", tweets[0]);
assertEquals("Caleb tweet content", tweetText, tweets[0].getContent());</span>
}</samp></pre>
A lot of objects are missing for this code to even compile: don't worry, you will remede to that in a few moments. But first, let's concentrate on the second user story.
</li>
<li>
In order to implement the second user story, create in the same manner a second method called <kbd>"testMultipleTweets"</kbd>, that take no parameters and return <code>void</code>, and with the <kbd>@Test</kbd> annotation:
<pre><samp>public class TwitterServiceFunctionalTest {
@Test
public void testSingleTweet() {
[...]
}
<span class="new">@Test
public void testMultipleTweets() {
}</span>
}</samp></pre>
</li>
<li>
Again, concentrating on the story itself, the second user story can be written like this:
<pre><samp>@Test
public void testMultipleTweets() {
<span class="new">String firstTweetText = "Grrrrr";
String secondTweetText = "I'm happy";
Kurtzmann.login();
Kurtzmann.getTweetService().tweet(firstTweetText);
Kurtzmann.getTweetService().tweet(secondTweetText);
Kurtzmann.logout();
Caleb.login();
Tweet[] tweets = Caleb.getTweetService().getTweetsOf(Kurtzmann.getProfile());
Caleb.logout();
assertEquals("There should be only two tweets", 2, tweets.length);
assertNotNull("First Kurtzmann tweet", tweets[0]);
assertNotNull("Second Kurtzmann tweet", tweets[1]);
assertEquals("First Kurtzmann tweet content", firstTweetText, tweets[0]);
assertEquals("Second Kurtzmann tweet content", secondTweetText, tweets[1]);</span>
}</samp></pre>
As for the first user story, a lot of objects are missing for this code to even compile.
</li>
<li>
To implement those stories, you need to create the <em>Caleb</em> and <em>Kurtzmann</em> object. Those objects are just wrapper for tests methods, so that the user story is easier to read (this is call that a <em>DSL</em>: <em>Domain Specific Language</em>). You need to define a specific class for those objects, a class that will answer to those methods. Let's call this class <em>"User"</em>, and let it be a inner class of <em>TwitterServiceFunctionalTest</em>:
<pre><samp>public class TwitterServiceFunctionalTest {
@Test
public void testSingleTweet() {
[...]
}
<span class="new">private class User {
}</span>
}</samp></pre>
</li>
<li>
Add to this class the necessary methods that will be called in your tests:
<pre><samp>private class User {
<span class="new">public void login() {
}
public void logout() {
}
public TweetService getTweetService() {
}
public String getProfile() {
}</span>
}</samp></pre>
</li>
<li>
An instance of this class will need only two informations, those necessary for login: the username and the password. Those information will be passed in the constructor. So add a constructor with the necessary parameters:
<pre><samp>private class User {
<span class="new">public User(String username, String password) {
}</span>
[...]
}</samp></pre>
</li>
<li>
<p>Now, you need to instantiate the objects so that they are ready for the tests. They have to be created before each test is running. To do this, you only need to put the code in a method and annotate this method with the <em>"@Before"</em> annotation. This JUnit annotation tells ejb3unit to run the annotated method before each test.</p>
<p>Create a new method called <em>"initialize"</em>, that take no parameters and return <code>void</code>, and annotate it with the <em>"@Before"</em> annotation:</p>
<pre><samp>public class TwitterServiceFunctionalTest {
<span class="new">@Before
public void initialize() {
}</span>
[...]
}</samp></pre>
</li>
<li>
</li>
</ol>
</div>
<div id="conclusion">
<p>In this page, you have defined your service, implemented the whole EJB part of it, and even tested it, with unit testing and functional testing. You now have a fonctional and tested EJB service. The main thing missing for it to be a fully functional factory service is to calls the necessary Qualipso Factory services, to be able to integrate in the factory. But before doing that, you will first add a <a href="remote.html">webservice remote access</a> to your service.</p>
</div>
</div>
</div>
<div id="footer">
<div id="validation">
<a class="xhtml" href="http://validator.w3.org/check?uri=referer">xhtml</a>
<a class="css" href="http://jigsaw.w3.org/css-validator/check/referer">css</a>
</div>
</div>
</body>
</html>