incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From conflue...@apache.org
Subject [CONF] Apache Sling Website > Testing Sling-based applications
Date Mon, 07 May 2012 23:39:00 GMT
<html>
<head>
    <base href="https://cwiki.apache.org/confluence">
            <link rel="stylesheet" href="/confluence/s/2042/9/1/_/styles/combined.css?spaceKey=SLINGxSITE&amp;forWysiwyg=true"
type="text/css">
    </head>
<body style="background: white;" bgcolor="white" class="email-body">
<div id="pageContent">
<div id="notificationFormat">
<div class="wiki-content">
<div class="email">
    <h2><a href="https://cwiki.apache.org/confluence/display/SLINGxSITE/Testing+Sling-based+applications">Testing
Sling-based applications</a></h2>
    <h4>Page <b>edited</b> by             <a href="https://cwiki.apache.org/confluence/display/~bdelacretaz">Bertrand
Delacretaz</a>
    </h4>
        <br/>
                         <h4>Changes (4)</h4>
                                 
    
<div id="page-diffs">
                    <table class="diff" cellpadding="0" cellspacing="0">
    
            <tr><td class="diff-snipped" >...<br></td></tr>
            <tr><td class="diff-unchanged" > <br>h1. Unit tests <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">When
possible, unit tests are obviously the fastest executing ones, and it&#39;s easy to keep
the close to the code that they&#39;re testing.  <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-deleted-lines" style="color:#999;background-color:#fdd;text-decoration:line-through;">h1.
Mocks <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">We
have quite a lot of those in Sling, the older use the JUnit3 TestCase base class, and later
ones use JUnit4 annotations. <br></td></tr>
            <tr><td class="diff-unchanged" > <br></td></tr>
            <tr><td class="diff-added-lines" style="background-color: #dfd;">h1.
Mock services <br>The next step is to use mock services to test components without requiring
an OSGi runtime. <br> <br>We have a number of custom-written mock services in
Sling, like [MockNodeType|https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/commons/testing/jcr/MockNodeType.java]
for example. These handwritten mocks implement just what&#39;s needed for their tests,
so they might not be reusable as is. <br> <br>In other cases we use [jmock|http://www.jmock.org/]
to help create mock objects without having to write much code - such mocking libraries take
care of the plumbing and allow you to write just the bits of code that matter (often with
funny syntaxes). The tests of the [org.apache.sling.event|https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/event/]
bundle, for example, make extensive use of such mock services. <br> <br>The problem
with mocks is that it can become hard to make sure you&#39;re actually testing something,
and not just &quot;mocking mocks&quot;. At a certain level of complexity, it becomes
quicker and clearer to actually start an OSGi framework for automated tests. <br> <br>h2.
Injecting services in private fields <br>To inject (real or fake) services in others
for testing, without having to create getters and setters just for this, we use a reflection-based
trick, as in this example: <br> <br>{code:title=setting a private field via reflection}
<br>// set resource resolver factory <br>// in a ServletResolver object which
has a private resourceResolverFactory field <br> <br>ServletResolver servletResolver
= .... <br>Class&lt;?&gt; resolverClass = servletResolver.getClass().getSuperclass();
<br>final java.lang.reflect.Field resolverField = resolverClass.getDeclaredField(&quot;resourceResolverFactory&quot;);
<br>resolverField.setAccessible(true); <br>resolverField.set(servletResolver,
factory); <br>{code} <br> <br> <br> <br></td></tr>
            <tr><td class="diff-unchanged" >h1. Pax Exam <br> <br></td></tr>
            <tr><td class="diff-snipped" >...<br></td></tr>
    
            </table>
    </div>                            <h4>Full Content</h4>
                    <div class="notificationGreySide">
        <p>Automated testing of OSGi components and services can be challenging, as
many of them depend on other services that must be present or simulated for testing.</p>

<p>This page explains the various approaches that we use to test Sling itself, and introduces
a number of tools that can help testing OSGi and HTTP-based applications.</p>

<h1><a name="TestingSling-basedapplications-Unittests"></a>Unit tests</h1>
<p>When possible, unit tests are obviously the fastest executing ones, and it's easy
to keep the close to the code that they're testing. </p>

<p>We have quite a lot of those in Sling, the older use the JUnit3 TestCase base class,
and later ones use JUnit4 annotations.</p>

<h1><a name="TestingSling-basedapplications-Mockservices"></a>Mock services</h1>
<p>The next step is to use mock services to test components without requiring an OSGi
runtime.</p>

<p>We have a number of custom-written mock services in Sling, like <a href="https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/testing/src/main/java/org/apache/sling/commons/testing/jcr/MockNodeType.java"
class="external-link" rel="nofollow">MockNodeType</a> for example. These handwritten
mocks implement just what's needed for their tests, so they might not be reusable as is.</p>

<p>In other cases we use <a href="http://www.jmock.org/" class="external-link" rel="nofollow">jmock</a>
to help create mock objects without having to write much code - such mocking libraries take
care of the plumbing and allow you to write just the bits of code that matter (often with
funny syntaxes). The tests of the <a href="https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/event/"
class="external-link" rel="nofollow">org.apache.sling.event</a> bundle, for example,
make extensive use of such mock services.</p>

<p>The problem with mocks is that it can become hard to make sure you're actually testing
something, and not just "mocking mocks". At a certain level of complexity, it becomes quicker
and clearer to actually start an OSGi framework for automated tests.</p>

<h2><a name="TestingSling-basedapplications-Injectingservicesinprivatefields"></a>Injecting
services in private fields</h2>
<p>To inject (real or fake) services in others for testing, without having to create
getters and setters just for this, we use a reflection-based trick, as in this example:</p>

<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader"
style="border-bottom-width: 1px;"><b>setting a private field via reflection</b></div><div
class="codeContent panelContent">
<pre class="code-java">
<span class="code-comment">// set resource resolver factory
</span><span class="code-comment">// in a ServletResolver object which has a <span
class="code-keyword">private</span> resourceResolverFactory field
</span>
ServletResolver servletResolver = ....
<span class="code-object">Class</span>&lt;?&gt; resolverClass = servletResolver.getClass().getSuperclass();
<span class="code-keyword">final</span> java.lang.reflect.Field resolverField
= resolverClass.getDeclaredField(<span class="code-quote">"resourceResolverFactory"</span>);
resolverField.setAccessible(<span class="code-keyword">true</span>);
resolverField.set(servletResolver, factory);
</pre>
</div></div>



<h1><a name="TestingSling-basedapplications-PaxExam"></a>Pax Exam</h1>

<h1><a name="TestingSling-basedapplications-Slingtestingtools%3AserversideJUnittests"></a>Sling
testing tools: server-side JUnit tests</h1>

<h1><a name="TestingSling-basedapplications-HTTPbasedintegrationtests"></a>HTTP-based
integration tests</h1>
    </div>
        <div id="commentsSection" class="wiki-content pageSection">
        <div style="float: right;">
            <a href="https://cwiki.apache.org/confluence/users/viewnotifications.action"
class="grey">Change Notification Preferences</a>
        </div>
        <a href="https://cwiki.apache.org/confluence/display/SLINGxSITE/Testing+Sling-based+applications">View
Online</a>
        |
        <a href="https://cwiki.apache.org/confluence/pages/diffpagesbyversion.action?pageId=27846122&revisedVersion=2&originalVersion=1">View
Changes</a>
                |
        <a href="https://cwiki.apache.org/confluence/display/SLINGxSITE/Testing+Sling-based+applications?showComments=true&amp;showCommentArea=true#addcomment">Add
Comment</a>
            </div>
</div>
</div>
</div>
</div>
</body>
</html>

Mime
View raw message