blob: 871b09691dc26e52565cc9d2b4bc8337f558436b [file]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(["setDoNotTrack", true]);
_paq.push(["disableCookies"]);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="https://analytics.apache.org/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '79']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
<title>15 Testing 5.3.6</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link rel="stylesheet" href="../css/main.css" type="text/css" media="screen, print" title="Style" charset="utf-8"/>
<link rel="stylesheet" href="../css/pdf.css" type="text/css" media="print" title="PDF" charset="utf-8"/>
<script type="text/javascript">
function addJsClass() {
var classes = document.body.className.split(" ");
classes.push("js");
document.body.className = classes.join(" ");
}
</script>
</head>
<body class="body" onload="addJsClass();">
<div id="navigation">
<div class="navTitle">
The Grails Framework
</div>
<div class="navLinks">
<ul>
<li>
<div id="nav-summary" onmouseover="toggleNavSummary(false)" onmouseout="toggleNavSummary(true)">
<a href="../guide/index.html" class="button">Table of contents</a>
<div id="nav-summary-childs" style="display:none;">
<div class="toc-item" style="margin-left:0"><a href="../guide/introduction.html"><strong>1</strong><span>Introduction</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/gettingStarted.html"><strong>2</strong><span>Getting Started</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/upgrading.html"><strong>3</strong><span>Upgrading from the previous versions</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/conf.html"><strong>4</strong><span>Configuration</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/commandLine.html"><strong>5</strong><span>The Command Line</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/profiles.html"><strong>6</strong><span>Application Profiles</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/GORM.html"><strong>7</strong><span>Object Relational Mapping (GORM)</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/theWebLayer.html"><strong>8</strong><span>The Web Layer</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/traits.html"><strong>9</strong><span>Traits</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/REST.html"><strong>10</strong><span>REST</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/async.html"><strong>11</strong><span>Asynchronous Programming</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/validation.html"><strong>12</strong><span>Validation</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/services.html"><strong>13</strong><span>The Service Layer</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/staticTypeCheckingAndCompilation.html"><strong>14</strong><span>Static Type Checking And Compilation</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/testing.html"><strong>15</strong><span>Testing</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/i18n.html"><strong>16</strong><span>Internationalization</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/security.html"><strong>17</strong><span>Security</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/plugins.html"><strong>18</strong><span>Plugins</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/spring.html"><strong>19</strong><span>Grails and Spring</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/scaffolding.html"><strong>20</strong><span>Scaffolding</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/deployment.html"><strong>21</strong><span>Deployment</span></a>
</div>
<div class="toc-item" style="margin-left:0"><a href="../guide/contributing.html"><strong>22</strong><span>Contributing to Grails</span></a>
</div>
</div>
</div>
</li>
<li class="separator selected">
<a id="ref-button" onclick="localToggle(); return false;" href="#">Quick Reference</a>
</li>
</ul>
</div>
</div>
<table id="colset" border="0" cellpadding="0" cellspacing="0">
<tr>
<td id="col1">
<div id="main" class="corner-all">
<div class="toc-item prev-left"><a href="../guide/staticTypeCheckingAndCompilation.html">&lt;&lt; <strong>14</strong><span>Static Type Checking And Compilation</span></a></div>
<span id='toggle-col1' class="toggle">(<a href="#" onclick="localToggle(); return false;">Quick Reference</a>)</span>
<div class="toc-item next-right"><a href="../guide/i18n.html"><strong>16</strong><span>Internationalization</span> >></a></div>
<div class="project">
<h1>15 Testing</h1>
<p><strong>Version:</strong> 5.3.6</p>
</div>
<div id="table-of-content">
<h2>Table of Contents</h2>
<div class="toc-item" style="margin-left:0px"><a href="#unitTesting"><strong>15.1</strong><span>Unit Testing</span></a>
</div>
<div class="toc-item" style="margin-left:0px"><a href="#integrationTesting"><strong>15.2</strong><span>Integration Testing</span></a>
</div>
<div class="toc-item" style="margin-left:0px"><a href="#functionalTesting"><strong>15.3</strong><span>Functional Testing</span></a>
</div>
</div>
<a name="12. Testing"><!-- Legacy link --></a>
<h1 id="testing">15 Testing</h1>
<div class='contribute-btn'>
<button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/5.3.x/src/en/guide/testing.adoc"'>
<i class='fa fa-pencil-square-o'></i> Improve this doc
</button>
</div>
<div class="paragraph">
<p>Automated testing is a key part of Grails. Hence, Grails provides many ways to making testing easier from low level unit testing to high level functional tests. This section details the different capabilities that Grails offers for testing.</p>
</div>
<div class="paragraph">
<p>The first thing to be aware of is that all of the <code>create-*</code> and <code>generate-\*</code> commands create <code>unit</code> or <code>integration</code> tests automatically. For example if you run the <a href="../ref/Command%20Line/create-controller.html">create-controller</a> command as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy">grails create-controller com.acme.app.simple</code></pre>
</div>
</div>
<div class="paragraph">
<p>Grails will create a controller at <code>grails-app/controllers/com/acme/app/SimpleController.groovy</code>, and also a unit test at <code>src/test/groovy/com/acme/app/SimpleControllerSpec.groovy</code>. What Grails won&#8217;t do however is populate the logic inside the test! That is left up to you.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The default class name suffix is <code>Tests</code> but as of Grails 1.2.2, the suffix of <code>Test</code> is also supported.
</td>
</tr>
</table>
</div>
<div class="sect3">
<h4 id="_running_tests">Running Tests</h4>
<div class="paragraph">
<p>Tests are run with the <a href="../ref/Command%20Line/test-app.html">test-app</a> command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy">grails test-app</code></pre>
</div>
</div>
<div class="paragraph">
<p>The command will produce output such as:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy">-------------------------------------------------------
Running Unit Tests...
Running test FooTests...FAILURE
Unit Tests Completed <span class="keyword">in</span> <span class="integer">464</span>ms ...
-------------------------------------------------------
Tests <span class="key">failed</span>: <span class="integer">0</span> errors, <span class="integer">1</span> failures</code></pre>
</div>
</div>
<div class="paragraph">
<p>whilst showing the reason for each test failure.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
You can force a clean before running tests by passing <code>-clean</code> to the <code>test-app</code> command.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Grails writes HTML test reports to the <code>build/reports/tests</code> directory and JUnit XML test reports to the <code>build/test-results</code> directory. The HTML reports are generally the best ones to look at.</p>
</div>
<div class="paragraph">
<p>Using Grails' <a href="commandLine.html#interactiveMode">interactive mode</a> confers some distinct advantages when executing tests. First, the tests will execute significantly faster on the second and subsequent runs. Second, a shortcut is available to open the HTML reports in your browser:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy">open test-report</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can also run your unit tests from within most IDEs.</p>
</div>
</div>
<div class="sect3">
<h4 id="_targeting_tests">Targeting Tests</h4>
<div class="paragraph">
<p>You can selectively target the test(s) to be run in different ways. To run all tests for a controller named <code>SimpleController</code> you would run:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy">grails test-app SimpleController</code></pre>
</div>
</div>
<div class="paragraph">
<p>This will run any tests for the class named <code>SimpleController</code>. Wildcards can be used&#8230;&#8203;</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy">grails test-app *Controller</code></pre>
</div>
</div>
<div class="paragraph">
<p>This will test all classes ending in <code>Controller</code>. Package names can optionally be specified&#8230;&#8203;</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy">grails test-app some.org.*Controller</code></pre>
</div>
</div>
<div class="paragraph">
<p>or to run all tests in a package&#8230;&#8203;</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy">grails test-app some.org.*</code></pre>
</div>
</div>
<div class="paragraph">
<p>or to run all tests in a package including subpackages&#8230;&#8203;</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy">grails test-app some.org.**.*</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can also target particular test methods&#8230;&#8203;</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy">grails test-app SimpleController.testLogin</code></pre>
</div>
</div>
<div class="paragraph">
<p>This will run the <code>testLogin</code> test in the <code>SimpleController</code> tests. You can specify as many patterns in combination as you like&#8230;&#8203;</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy">grails test-app some.org.* SimpleController.testLogin BookController</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
In Grails 2.x, adding <code>-rerun</code> as an argument would only run those tests which failed in the previous test-app run. This argument is no longer supported.
</td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
In Grails 3.x, you might need to specify the package name before the class name, as well as append "Spec" to the end. For example, if you want to run the test for the ProductController, you should use <code>grails test-app *.ProductControllerSpec</code>. Note that the star can be used if you don&#8217;t want to type the whole package hierarchy.
</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="_debugging">Debugging</h4>
<div class="paragraph">
<p>In order to debug your tests via a remote debugger, you can add <code>--debug-jvm</code> after <code>grails</code> in any commands, like so:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy">grails --debug-jvm test-app</code></pre>
</div>
</div>
<div class="paragraph">
<p>This will open the default Java remote debugging port, 5005, for you to attach a remote debugger from your editor / IDE of choice.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
This differs from Grails 2.3 and previous, where the <code>grails-debug</code> command existed.
</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="_targeting_test_phases">Targeting Test Phases</h4>
<div class="paragraph">
<p>In addition to targeting certain tests, you can also target test <em>phases.</em> By default Grails has two testing phases <code>unit</code> and <code>integration.</code></p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Grails 2.x uses <code>phase:type</code> syntax. In Grails 3.0 it was removed, because it made no sense in Gradle context.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>To execute <code>unit</code> tests you can run:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy">grails test-app -unit</code></pre>
</div>
</div>
<div class="paragraph">
<p>To run <code>integration</code> tests you would run&#8230;&#8203;</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy">grails test-app -integration</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_targeting_tests_when_using_phases">Targeting Tests When Using Phases</h4>
<div class="paragraph">
<p>Test and phase targeting can be applied at the same time:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy">grails test-app some.org.**.* -unit</code></pre>
</div>
</div>
<div class="paragraph">
<p>This would run all tests in the <code>unit</code> phase that are in the package <code>some.org</code> or a subpackage.</p>
</div>
</div>
<a name="12.1 Unit Testing"><!-- Legacy link --></a>
<h2 id="unitTesting">15.1 Unit Testing</h2>
<div class='contribute-btn'>
<button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/5.3.x/src/en/guide/testing/unitTesting.adoc"'>
<i class='fa fa-pencil-square-o'></i> Improve this doc
</button>
</div>
<div class="paragraph">
<p>Unit testing are tests at the "unit" level. In other words you are testing individual methods or blocks of code without consideration for surrounding infrastructure. Unit tests are typically run without the presence of physical resources that involve I/O such as databases, socket connections or files. This is to ensure they run as quick as possible since quick feedback is important.</p>
</div>
<div class="paragraph">
<p>Since Grails 3.3, the <a href="https://testing.grails.org">Grails Testing Support Framework</a> is used for all unit tests. This support provides a set of traits. An example hello world test can be seen below:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy"><span class="keyword">import</span> <span class="include">spock.lang.Specification</span>
<span class="keyword">import</span> <span class="include">grails.testing.web.controllers.ControllerUnitTest</span>
<span class="type">class</span> <span class="class">HelloControllerTests</span> <span class="directive">extends</span> Specification <span class="directive">implements</span> ControllerUnitTest&lt;HelloController&gt; {
<span class="type">void</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">Test message action</span><span class="delimiter">&quot;</span></span>() {
<span class="key">when</span>:<span class="string"><span class="delimiter">&quot;</span><span class="content">The message action is invoked</span><span class="delimiter">&quot;</span></span>
controller.message()
<span class="key">then</span>:<span class="string"><span class="delimiter">&quot;</span><span class="content">Hello is returned</span><span class="delimiter">&quot;</span></span>
response.text == <span class="string"><span class="delimiter">'</span><span class="content">Hello</span><span class="delimiter">'</span></span>
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>For more information on writing tests with Grails Testing Support see the <a href="https://testing.grails.org">dedicated documentation</a>.</p>
</div>
<div class="paragraph">
<p>Versions of Grails below 3.2 used the <a href="https://grails-plugins.github.io/grails-test-mixin-plugin/latest/guide/index.html">Grails Test Mixin Framework</a> which was based on the <code>@TestMixin</code> AST transformation. This library has been superceded by the simpler and more IDE friendly trait based implementation.</p>
</div>
<a name="12.2 Integration Testing"><!-- Legacy link --></a>
<h2 id="integrationTesting">15.2 Integration Testing</h2>
<div class='contribute-btn'>
<button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/5.3.x/src/en/guide/testing/integrationTesting.adoc"'>
<i class='fa fa-pencil-square-o'></i> Improve this doc
</button>
</div>
<div class="paragraph">
<p>Integration tests differ from unit tests in that you have full access to the Grails environment within the test. You can create an integration test using the <a href="../ref/Command%20Line/create-integration-test.html">create-integration-test</a> command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy"><span class="error">$</span> grails create-integration-test Example</code></pre>
</div>
</div>
<div class="paragraph">
<p>The above command will create a new integration test at the location <code>src/integration-test/groovy/&lt;PACKAGE&gt;/ExampleSpec.groovy</code>.</p>
</div>
<div class="paragraph">
<p>Grails uses the test environment for integration tests and loads the application prior to the first test run. All tests use the same application state.</p>
</div>
<div class="sect3">
<h4 id="_transactions">Transactions</h4>
<div class="paragraph">
<p>Integration test methods run inside their own database transaction by default, which is rolled back at the end of each test method. This means that data saved during a test is not persisted to the database (which is shared across all tests). The default generated integration test template includes the <a href="https://grails.apache.org/docs/5.3.6/api/grails/transaction/Rollback.html">Rollback</a> annotation:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy"><span class="keyword">import</span> <span class="include">grails.testing.mixin.integration.Integration</span>
<span class="keyword">import</span> <span class="include">grails.gorm.transactions.*</span>
<span class="keyword">import</span> <span class="include">spock.lang.*</span>
<span class="annotation">@Integration</span>
<span class="annotation">@Rollback</span>
<span class="type">class</span> <span class="class">ExampleSpec</span> <span class="directive">extends</span> Specification {
...
void <span class="string"><span class="delimiter">&quot;</span><span class="content">test something</span><span class="delimiter">&quot;</span></span>() {
<span class="key">expect</span>:<span class="string"><span class="delimiter">&quot;</span><span class="content">fix me</span><span class="delimiter">&quot;</span></span>
<span class="predefined-constant">true</span> == <span class="predefined-constant">false</span>
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>Rollback</code> annotation ensures that each test method runs in a transaction that is rolled back. Generally this is desirable because you do not want your tests depending on order or application state.</p>
</div>
<div class="paragraph">
<p>In Grails 3.0 tests rely on <code>grails.gorm.transactions.Rollback</code> annotation to bind the session in integration tests. Though each test method transaction is rolled back, the <code>setup()</code> method uses a separate transaction that is not rolled back.
Data will persist to the database and will need to be cleaned up manually if <code>setup()</code> sets up data and persists them as shown in the below sample:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy"><span class="keyword">import</span> <span class="include">grails.testing.mixin.integration.Integration</span>
<span class="keyword">import</span> <span class="include">grails.gorm.transactions.*</span>
<span class="keyword">import</span> <span class="include">spock.lang.*</span>
<span class="annotation">@Integration</span>
<span class="annotation">@Rollback</span>
<span class="type">class</span> <span class="class">BookSpec</span> <span class="directive">extends</span> Specification {
<span class="type">void</span> setup() {
<span class="comment">// Below line would persist and not roll back</span>
<span class="keyword">new</span> <span class="predefined-type">Book</span>(<span class="key">name</span>: <span class="string"><span class="delimiter">'</span><span class="content">Grails in Action</span><span class="delimiter">'</span></span>).save(<span class="key">flush</span>: <span class="predefined-constant">true</span>)
}
<span class="type">void</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">test something</span><span class="delimiter">&quot;</span></span>() {
<span class="key">expect</span>:
<span class="predefined-type">Book</span>.count() == <span class="integer">1</span>
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>To preload the database and automatically roll back setup logic, any persistence operations need to be called from the test method itself so that they can run within the test method&#8217;s rolled back transaction. Similar to usage of the <code>setupData()</code> method shown below which creates a record in database and after running other test will be rolled back:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy"><span class="keyword">import</span> <span class="include">grails.testing.mixin.integration.Integration</span>
<span class="keyword">import</span> <span class="include">grails.gorm.transactions.*</span>
<span class="keyword">import</span> <span class="include">spock.lang.*</span>
<span class="annotation">@Integration</span>
<span class="annotation">@Rollback</span>
<span class="type">class</span> <span class="class">BookSpec</span> <span class="directive">extends</span> Specification {
<span class="type">void</span> setupData() {
<span class="comment">// Below line would roll back</span>
<span class="keyword">new</span> <span class="predefined-type">Book</span>(<span class="key">name</span>: <span class="string"><span class="delimiter">'</span><span class="content">Grails in Action</span><span class="delimiter">'</span></span>).save(<span class="key">flush</span>: <span class="predefined-constant">true</span>)
}
<span class="type">void</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">test something</span><span class="delimiter">&quot;</span></span>() {
<span class="key">given</span>:
setupData()
<span class="key">expect</span>:
<span class="predefined-type">Book</span>.count() == <span class="integer">1</span>
}
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_using_springs_rollback_annotation">Using Spring&#8217;s Rollback annotation</h4>
<div class="paragraph">
<p>Another transactional approach could be to use Spring&#8217;s <a href="https://docs.spring.io/spring/docs/5.3.8/javadoc-api/org/springframework/test/annotation/Rollback.html">@Rollback</a> instead.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy"><span class="keyword">import</span> <span class="include">grails.testing.mixin.integration.Integration</span>
<span class="keyword">import</span> <span class="include">org.springframework.test.annotation.Rollback</span>
<span class="keyword">import</span> <span class="include">spock.lang.*</span>
<span class="annotation">@Integration</span>
<span class="annotation">@Rollback</span>
<span class="type">class</span> <span class="class">BookSpec</span> <span class="directive">extends</span> Specification {
<span class="type">void</span> setup() {
<span class="keyword">new</span> <span class="predefined-type">Book</span>(<span class="key">name</span>: <span class="string"><span class="delimiter">'</span><span class="content">Grails in Action</span><span class="delimiter">'</span></span>).save(<span class="key">flush</span>: <span class="predefined-constant">true</span>)
}
<span class="type">void</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">test something</span><span class="delimiter">&quot;</span></span>() {
<span class="key">expect</span>:
<span class="predefined-type">Book</span>.count() == <span class="integer">1</span>
}
}</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
It isn&#8217;t possible to make <code>grails.gorm.transactions.Rollback</code> behave the same way as Spring&#8217;s Rollback annotation because <code>grails.gorm.transactions.Rollback</code> transforms the byte code of the class, eliminating the need for a proxy (which Spring&#8217;s version requires).
This has the downside that you cannot implement it differently for different cases (as Spring does for testing).
</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="_dirtiescontext">DirtiesContext</h4>
<div class="paragraph">
<p>If you do have a series of tests that will share state you can remove the <code>Rollback</code> and the last test in the suite should feature the <a href="https://docs.spring.io/spring/docs/5.3.8/javadoc-api/org/springframework/test/annotation/DirtiesContext.html">DirtiesContext</a> annotation which will shutdown the environment and restart it fresh (note that this will have an impact on test run times).</p>
</div>
</div>
<div class="sect3">
<h4 id="_autowiring">Autowiring</h4>
<div class="paragraph">
<p>To obtain a reference to a bean you can use the <a href="https://docs.spring.io/spring/docs/5.3.8/javadoc-api/org/springframework/beans/factory/annotation/Autowired.html">Autowired</a> annotation. For example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy">...
import org.springframework.beans.factory.annotation.*
<span class="annotation">@Integration</span>
<span class="annotation">@Rollback</span>
<span class="type">class</span> <span class="class">ExampleServiceSpec</span> <span class="directive">extends</span> Specification {
<span class="annotation">@Autowired</span>
ExampleService exampleService
...
void <span class="string"><span class="delimiter">&quot;</span><span class="content">Test example service</span><span class="delimiter">&quot;</span></span>() {
<span class="key">expect</span>:
exampleService.countExamples() == <span class="integer">0</span>
}
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_testing_controllers">Testing Controllers</h4>
<div class="paragraph">
<p>To integration test controllers it is recommended you use <a href="../ref/Command%20Line/create-functional-test.html">create-functional-test</a> command to create a Geb functional test. See the following section on functional testing for more information.</p>
</div>
</div>
<a name="12.3 Functional Testing"><!-- Legacy link --></a>
<h2 id="functionalTesting">15.3 Functional Testing</h2>
<div class='contribute-btn'>
<button type='button' class='btn btn-default' onclick='window.location.href="https://github.com/grails/grails-doc/edit/5.3.x/src/en/guide/testing/functionalTesting.adoc"'>
<i class='fa fa-pencil-square-o'></i> Improve this doc
</button>
</div>
<div class="paragraph">
<p>Functional tests involve making HTTP requests against the running application and verifying the resultant behaviour. This is useful for end-to-end testing scenarios, such as making REST calls against a JSON API.</p>
</div>
<div class="paragraph">
<p>Grails by default ships with support for writing functional tests using the <a href="http://www.gebish.org">Geb framework</a>. To create a functional test you can use the <code>create-functional-test</code> command which will create a new functional test:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy"><span class="error">$</span> grails create-functional-test MyFunctional</code></pre>
</div>
</div>
<div class="paragraph">
<p>The above command will create a new Spock spec called <code>MyFunctionalSpec.groovy</code> in the <code>src/integration-test/groovy</code> directory. The test is annotated with the <a href="https://grails.apache.org/docs/5.3.6/api/grails/test/mixin/integration/Integration.html">Integration</a> annotation to indicate it is an integration test and extends the <code>GebSpec</code> super class:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy"><span class="annotation">@Integration</span>
<span class="type">class</span> <span class="class">HomeSpec</span> <span class="directive">extends</span> GebSpec {
<span class="keyword">def</span> <span class="function">setup</span>() {
}
<span class="keyword">def</span> <span class="function">cleanup</span>() {
}
<span class="type">void</span> <span class="string"><span class="delimiter">&quot;</span><span class="content">Test the home page renders correctly</span><span class="delimiter">&quot;</span></span>() {
<span class="key">when</span>:<span class="string"><span class="delimiter">&quot;</span><span class="content">The home page is visited</span><span class="delimiter">&quot;</span></span>
go <span class="string"><span class="delimiter">'</span><span class="content">/</span><span class="delimiter">'</span></span>
<span class="key">then</span>:<span class="string"><span class="delimiter">&quot;</span><span class="content">The title is correct</span><span class="delimiter">&quot;</span></span>
<span class="error">$</span>(<span class="string"><span class="delimiter">'</span><span class="content">title</span><span class="delimiter">'</span></span>).text() == <span class="string"><span class="delimiter">&quot;</span><span class="content">Welcome to Grails</span><span class="delimiter">&quot;</span></span>
}
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>When the test is run the application container will be loaded up in the background and you can send requests to the running application using the Geb API.</p>
</div>
<div class="paragraph">
<p>Note that the application is only loaded once for the entire test run, so functional tests share the state of the application across the whole suite.</p>
</div>
<div class="paragraph">
<p>In addition the application is loaded in the JVM as the test, this means that the test has full access to the application state and can interact directly with data services such as GORM to setup and cleanup test data.</p>
</div>
<div class="paragraph">
<p>The <code>Integration</code> annotation supports an optional <code>applicationClass</code> attribute which may be used to specify the application class to use for the functional test. The class must extend <a href="https://grails.apache.org/docs/5.3.6/api/grails/boot/config/GrailsAutoConfiguration.html">GrailsAutoConfiguration</a>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy"><span class="annotation">@Integration</span>(applicationClass=com.demo.Application)
<span class="type">class</span> <span class="class">HomeSpec</span> <span class="directive">extends</span> GebSpec {
<span class="comment">// ...</span>
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>If the <code>applicationClass</code> is not specified then the test runtime environment will attempt to locate the application class dynamically which can be problematic in multiproject builds where multiple application classes may be present.</p>
</div>
<div class="paragraph">
<p>When running the server port by default will be randomly assigned. The <code>Integration</code> annotation adds a property of <code>serverPort</code> to the test class that you can use if you want to know what port the application is running on this isn&#8217;t needed if you are extending the <code>GebSpec</code> as shown above but can be useful information.</p>
</div>
<div class="paragraph">
<p>If you want to run the tests on a fixed port (defined by the <code>server.port</code> configuration property), you need to manually annotate your test with <code>@SpringBootTest</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="groovy"><span class="keyword">import</span> <span class="include">grails.testing.mixin.integration.Integration</span>
<span class="keyword">import</span> <span class="include">org.springframework.boot.test.context.SpringBootTest</span>
<span class="keyword">import</span> <span class="include">spock.lang.Specification</span>
<span class="annotation">@Integration</span>
<span class="annotation">@SpringBootTest</span>(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
<span class="type">class</span> <span class="class">MySpec</span> <span class="directive">extends</span> Specification {
<span class="comment">// ...</span>
}</code></pre>
</div>
</div>
<div style="clear:both;margin-top:15px;"></div>
<div class="toc-item prev-left"><a href="../guide/staticTypeCheckingAndCompilation.html">&lt;&lt; <strong>14</strong><span>Static Type Checking And Compilation</span></a></div>
<div class="toc-item next-right"><a href="../guide/i18n.html"><strong>16</strong><span>Internationalization</span> >></a></div>
<div style="clear:both"></div>
</div>
</td>
<td id="col2">
<div class="local clearfix">
<div class="local-title">
<a href="../guide/index.html" target="mainFrame">Quick Reference</a>
<span class="toggle">(<a href="#" onclick="localToggle(); return false;">hide</a>)</span>
</div>
<div class="menu">
<div class="menu-block"><h1 class="menu-title" onclick="toggleRef(this.parentNode.childNodes[1])">Command Line</h1><div class="menu-sub">
<div class="menu-item"><a href="../ref/Command%20Line/Usage.html">Usage</a></div>
<div class="menu-item"><a href="../ref/Command%20Line/bug-report.html">bug-report</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/clean.html">clean</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/compile.html">compile</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/console.html">console</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/create-app.html">create-app</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/create-command.html">create-command</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/create-controller.html">create-controller</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/create-domain-class.html">create-domain-class</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/create-functional-test.html">create-functional-test</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/create-hibernate-cfg-xml.html">create-hibernate-cfg-xml</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/create-integration-test.html">create-integration-test</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/create-interceptor.html">create-interceptor</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/create-plugin.html">create-plugin</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/create-profile.html">create-profile</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/create-script.html">create-script</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/create-service.html">create-service</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/create-taglib.html">create-taglib</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/create-unit-test.html">create-unit-test</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/dependency-report.html">dependency-report</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/docs.html">docs</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/generate-all.html">generate-all</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/generate-controller.html">generate-controller</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/generate-views.html">generate-views</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/help.html">help</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/install-templates.html">install-templates</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/list-plugins.html">list-plugins</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/list-profiles.html">list-profiles</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/package-plugin.html">package-plugin</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/package.html">package</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/plugin-info.html">plugin-info</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/profile-info.html">profile-info</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/run-app.html">run-app</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/run-command.html">run-command</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/run-script.html">run-script</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/schema-export.html">schema-export</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/shell.html">shell</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/stats.html">stats</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/stop-app.html">stop-app</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/test-app.html">test-app</a>
</div>
<div class="menu-item"><a href="../ref/Command%20Line/war.html">war</a>
</div>
</div>
</div>
<div class="menu-block"><h1 class="menu-title" onclick="toggleRef(this.parentNode.childNodes[1])">Constraints</h1><div class="menu-sub">
<div class="menu-item"><a href="../ref/Constraints/Usage.html">Usage</a></div>
<div class="menu-item"><a href="../ref/Constraints/attributes.html">attributes</a>
</div>
<div class="menu-item"><a href="../ref/Constraints/bindable.html">bindable</a>
</div>
<div class="menu-item"><a href="../ref/Constraints/blank.html">blank</a>
</div>
<div class="menu-item"><a href="../ref/Constraints/creditCard.html">creditCard</a>
</div>
<div class="menu-item"><a href="../ref/Constraints/email.html">email</a>
</div>
<div class="menu-item"><a href="../ref/Constraints/inList.html">inList</a>
</div>
<div class="menu-item"><a href="../ref/Constraints/matches.html">matches</a>
</div>
<div class="menu-item"><a href="../ref/Constraints/max.html">max</a>
</div>
<div class="menu-item"><a href="../ref/Constraints/maxSize.html">maxSize</a>
</div>
<div class="menu-item"><a href="../ref/Constraints/min.html">min</a>
</div>
<div class="menu-item"><a href="../ref/Constraints/minSize.html">minSize</a>
</div>
<div class="menu-item"><a href="../ref/Constraints/notEqual.html">notEqual</a>
</div>
<div class="menu-item"><a href="../ref/Constraints/nullable.html">nullable</a>
</div>
<div class="menu-item"><a href="../ref/Constraints/range.html">range</a>
</div>
<div class="menu-item"><a href="../ref/Constraints/scale.html">scale</a>
</div>
<div class="menu-item"><a href="../ref/Constraints/size.html">size</a>
</div>
<div class="menu-item"><a href="../ref/Constraints/unique.html">unique</a>
</div>
<div class="menu-item"><a href="../ref/Constraints/url.html">url</a>
</div>
<div class="menu-item"><a href="../ref/Constraints/validator.html">validator</a>
</div>
<div class="menu-item"><a href="../ref/Constraints/widget.html">widget</a>
</div>
</div>
</div>
<div class="menu-block"><h1 class="menu-title" onclick="toggleRef(this.parentNode.childNodes[1])">Controllers</h1><div class="menu-sub">
<div class="menu-item"><a href="../ref/Controllers/Usage.html">Usage</a></div>
<div class="menu-item"><a href="../ref/Controllers/actionName.html">actionName</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/allowedMethods.html">allowedMethods</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/bindData.html">bindData</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/chain.html">chain</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/controllerName.html">controllerName</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/defaultAction.html">defaultAction</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/errors.html">errors</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/flash.html">flash</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/forward.html">forward</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/grailsApplication.html">grailsApplication</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/hasErrors.html">hasErrors</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/header.html">header</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/namespace.html">namespace</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/params.html">params</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/redirect.html">redirect</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/render.html">render</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/request.html">request</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/respond.html">respond</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/response.html">response</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/responseFormats.html">responseFormats</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/scope.html">scope</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/servletContext.html">servletContext</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/session.html">session</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/withForm.html">withForm</a>
</div>
<div class="menu-item"><a href="../ref/Controllers/withFormat.html">withFormat</a>
</div>
</div>
</div>
<div class="menu-block"><h1 class="menu-title" onclick="toggleRef(this.parentNode.childNodes[1])">Database Mapping</h1><div class="menu-sub">
<div class="menu-item"><a href="../ref/Database%20Mapping/Usage.html">Usage</a></div>
<div class="menu-item"><a href="../ref/Database%20Mapping/autoImport.html">autoImport</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/autoTimestamp.html">autoTimestamp</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/batchSize.html">batchSize</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/cache.html">cache</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/cascade.html">cascade</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/column.html">column</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/comment.html">comment</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/discriminator.html">discriminator</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/dynamicInsert.html">dynamicInsert</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/dynamicUpdate.html">dynamicUpdate</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/fetch.html">fetch</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/id.html">id</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/ignoreNotFound.html">ignoreNotFound</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/indexColumn.html">indexColumn</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/insertable.html">insertable</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/joinTable.html">joinTable</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/lazy.html">lazy</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/order.html">order</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/sort.html">sort</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/table.html">table</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/type.html">type</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/updateable.html">updateable</a>
</div>
<div class="menu-item"><a href="../ref/Database%20Mapping/version.html">version</a>
</div>
</div>
</div>
<div class="menu-block"><h1 class="menu-title" onclick="toggleRef(this.parentNode.childNodes[1])">Domain Classes</h1><div class="menu-sub">
<div class="menu-item"><a href="../ref/Domain%20Classes/Usage.html">Usage</a></div>
<div class="menu-item"><a href="../ref/Domain%20Classes/addTo.html">addTo</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/attach.html">attach</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/belongsTo.html">belongsTo</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/clearErrors.html">clearErrors</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/constraints.html">constraints</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/count.html">count</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/countBy.html">countBy</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/createCriteria.html">createCriteria</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/delete.html">delete</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/discard.html">discard</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/embedded.html">embedded</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/errors.html">errors</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/executeQuery.html">executeQuery</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/executeUpdate.html">executeUpdate</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/exists.html">exists</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/fetchMode.html">fetchMode</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/find.html">find</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/findAll.html">findAll</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/findAllBy.html">findAllBy</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/findAllWhere.html">findAllWhere</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/findBy.html">findBy</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/findOrCreateBy.html">findOrCreateBy</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/findOrCreateWhere.html">findOrCreateWhere</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/findOrSaveBy.html">findOrSaveBy</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/findOrSaveWhere.html">findOrSaveWhere</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/findWhere.html">findWhere</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/first.html">first</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/get.html">get</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/getAll.html">getAll</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/getDirtyPropertyNames.html">getDirtyPropertyNames</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/getPersistentValue.html">getPersistentValue</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/hasErrors.html">hasErrors</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/hasMany.html">hasMany</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/hasOne.html">hasOne</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/ident.html">ident</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/instanceOf.html">instanceOf</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/isAttached.html">isAttached</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/isDirty.html">isDirty</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/last.html">last</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/list.html">list</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/listOrderBy.html">listOrderBy</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/load.html">load</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/lock.html">lock</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/mapWith.html">mapWith</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/mappedBy.html">mappedBy</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/mapping.html">mapping</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/merge.html">merge</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/namedQueries.html">namedQueries</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/properties.html">properties</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/read.html">read</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/refresh.html">refresh</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/removeFrom.html">removeFrom</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/save.html">save</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/transients.html">transients</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/validate.html">validate</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/where.html">where</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/whereAny.html">whereAny</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/withCriteria.html">withCriteria</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/withNewSession.html">withNewSession</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/withSession.html">withSession</a>
</div>
<div class="menu-item"><a href="../ref/Domain%20Classes/withTransaction.html">withTransaction</a>
</div>
</div>
</div>
<div class="menu-block"><h1 class="menu-title" onclick="toggleRef(this.parentNode.childNodes[1])">Plug-ins</h1><div class="menu-sub">
<div class="menu-item"><a href="../ref/Plug-ins/Usage.html">Usage</a></div>
<div class="menu-item"><a href="../ref/Plug-ins/URL%20mappings.html">URL mappings</a>
</div>
<div class="menu-item"><a href="../ref/Plug-ins/codecs.html">codecs</a>
</div>
<div class="menu-item"><a href="../ref/Plug-ins/controllers.html">controllers</a>
</div>
<div class="menu-item"><a href="../ref/Plug-ins/core.html">core</a>
</div>
<div class="menu-item"><a href="../ref/Plug-ins/dataSource.html">dataSource</a>
</div>
<div class="menu-item"><a href="../ref/Plug-ins/domainClasses.html">domainClasses</a>
</div>
<div class="menu-item"><a href="../ref/Plug-ins/hibernate.html">hibernate</a>
</div>
<div class="menu-item"><a href="../ref/Plug-ins/i18n.html">i18n</a>
</div>
<div class="menu-item"><a href="../ref/Plug-ins/logging.html">logging</a>
</div>
<div class="menu-item"><a href="../ref/Plug-ins/scaffolding.html">scaffolding</a>
</div>
<div class="menu-item"><a href="../ref/Plug-ins/services.html">services</a>
</div>
<div class="menu-item"><a href="../ref/Plug-ins/servlets.html">servlets</a>
</div>
</div>
</div>
<div class="menu-block"><h1 class="menu-title" onclick="toggleRef(this.parentNode.childNodes[1])">Services</h1><div class="menu-sub">
<div class="menu-item"><a href="../ref/Services/Usage.html">Usage</a></div>
<div class="menu-item"><a href="../ref/Services/scope.html">scope</a>
</div>
</div>
</div>
<div class="menu-block"><h1 class="menu-title" onclick="toggleRef(this.parentNode.childNodes[1])">Servlet API</h1><div class="menu-sub">
<div class="menu-item"><a href="../ref/Servlet%20API/request.html">request</a>
</div>
<div class="menu-item"><a href="../ref/Servlet%20API/response.html">response</a>
</div>
<div class="menu-item"><a href="../ref/Servlet%20API/servletContext.html">servletContext</a>
</div>
<div class="menu-item"><a href="../ref/Servlet%20API/session.html">session</a>
</div>
</div>
</div>
</div>
</div>
</td>
</tr>
</table>
<div id="footer">
Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.
</div>
<script type="text/javascript" src="../js/docs.js"></script>
</body>
</html>