A canonical Repository test

There are only so many ways to test that your persistence layer is implemented correctly or that you’re using an ORM correctly. Here’s my canonical tests for a repository (Java-version):

<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">static</span> org.<span style="color: #006633;">fest</span>.<span style="color: #006633;">assertions</span>.<span style="color: #006633;">api</span>.<span style="color: #006633;">Assertions</span>.<span style="color: #339933;">*;</span>
 
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> PersonRepositoryTest <span style="color: #009900;">{</span>
    <span style="color: #000000; font-weight: bold;">private</span> PersonRepository repository<span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// TODO < == you must initialize this</span>
 
    @Test
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> shouldSaveAllProperties<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
        Person person <span style="color: #339933;">=</span> randomPerson<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
        repository.<span style="color: #006633;">save</span><span style="color: #009900;">(</span>person<span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// TODO: Make sure your repository flushes!</span>
        assertThat<span style="color: #009900;">(</span>repository.<span style="color: #006633;">find</span><span style="color: #009900;">(</span>person.<span style="color: #006633;">getId</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span>
            .<span style="color: #006633;">isNotSameAs</span><span style="color: #009900;">(</span>person<span style="color: #009900;">)</span>
            .<span style="color: #006633;">isEqualTo</span><span style="color: #009900;">(</span>person<span style="color: #009900;">)</span>
            .<span style="color: #006633;">isEqualsToByComparingFields</span><span style="color: #009900;">(</span>person<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">}</span>
 
    @Test
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> shouldFindByCaseInsensitiveSubstringOfName<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
        Person matching <span style="color: #339933;">=</span> randomPerson<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
        Person nonMatching <span style="color: #339933;">=</span> randomPerson<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
        matching.<span style="color: #006633;">setName</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"A. Matching Person"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
        nonMatching.<span style="color: #006633;">setName</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"A. Random Person"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
        repository.<span style="color: #006633;">save</span><span style="color: #009900;">(</span>matching<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
        repository.<span style="color: #006633;">save</span><span style="color: #009900;">(</span>nonMatching<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
        assertThat<span style="color: #009900;">(</span>repository.<span style="color: #006633;">findByNameLike</span><span style="color: #009900;">(</span><span style="color: #0000ff;">"MATCH"</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span>
            .<span style="color: #006633;">contains</span><span style="color: #009900;">(</span>matching<span style="color: #009900;">)</span>
            .<span style="color: #006633;">doesNotContain</span><span style="color: #009900;">(</span>nonMatching<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">}</span>
<span style="color: #009900;">}</span>

Very simple. The randomPerson test helper generates actually random people:

<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> PersonTest <span style="color: #009900;">{</span>
    <span style="color: #666666; font-style: italic;">// ....</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> Person randomPerson<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
        Person person <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Pesron<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
        person.<span style="color: #006633;">setName</span><span style="color: #009900;">(</span>randomName<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">// TODO Initialize all properties</span>
        <span style="color: #000000; font-weight: bold;">return</span> person<span style="color: #339933;">;</span>
    <span style="color: #009900;">}</span>
 
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399;">String</span> randomName<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
        <span style="color: #000000; font-weight: bold;">return</span> RandomData.<span style="color: #006633;">randomWord</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">" "</span> <span style="color: #339933;">+</span> RandomData.<span style="color: #006633;">randomWord</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">"son"</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">}</span>
<span style="color: #009900;">}</span>
 
 
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> RandomData <span style="color: #009900;">{</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399;">String</span> randomString<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
        <span style="color: #000000; font-weight: bold;">return</span> random<span style="color: #009900;">(</span><span style="color: #0000ff;">"foo"</span>, <span style="color: #0000ff;">"bar"</span>, <span style="color: #0000ff;">"baz"</span>, <span style="color: #0000ff;">"qux"</span>, <span style="color: #0000ff;">"quux"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// TODO: Add more!</span>
    <span style="color: #009900;">}</span>
 
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #339933;"><</span>T<span style="color: #339933;">></span> T random<span style="color: #009900;">(</span>T... <span style="color: #006633;">options</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
        <span style="color: #000000; font-weight: bold;">return</span> options<span style="color: #009900;">[</span>random<span style="color: #009900;">(</span>options.<span style="color: #006633;">length</span><span style="color: #009900;">)</span><span style="color: #009900;">]</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">}</span>
 
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">int</span> random<span style="color: #009900;">(</span><span style="color: #000066; font-weight: bold;">int</span> max<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
        <span style="color: #000000; font-weight: bold;">return</span> random.<span style="color: #006633;">nextInt</span><span style="color: #009900;">(</span>max<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">}</span>
 
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399;">Random</span> random <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">Random</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>

If your data has relationships with other entities, you may want to include those as well:

Related:
1 2 Page 1
Notice to our Readers
We're now using social media to take your comments and feedback. Learn more about this here.