What You'll Learn

If we can test the service in isolation and we can test the controller in isolation, it makes sense that we would also want to test repositories in isolation.

But, what does "isolation" mean here? We could choose to mock the actual database. There are ways of doing this, but I will leave that as an exercise for you.

In this example, we are going to test the repository and the H2 database. We'll populate the database with known data, stimulate the repository and check the results.

Let's start with a test that checks that a select works.

Add a new class called CharityDataJDBCTests.java (you should know where).

In CharityDataJDBCTests.java.

@JdbcTest
@Sql(scripts={"/schema-test-h2.sql","/data-test-h2.sql"})
@DirtiesContext
public class CharityDataJDBCTests {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    CharityRepository charityRepository;
    ...
}
enough to run a database test.  It won't load controllers, etc.

```@DirtiesContext``` - again this tells Spring that the tests might
change the context so it needs to be refreshed after every test.

We want Spring to provide a ```JdbcTemplate``` bean and inject it, so 
that we can use it later in our methods. 

### A test method

In **CharityDataJDBCTests.java**.

```java
@Test
public void shouldGet11Charities() throws Exception{

        charityRepository = new CharityRepositoryJDBC(jdbcTemplate);

        List<Charity> charityList = charityRepository.findAll();
        assertEquals(11, charityList.size());
        }

This test creates a new instance of the repository, injecting the JdbcTemplate. It then calls a method on it and asserts that the number of rows returned is correct. What we're really testing here is that the repository issues the correct query and maps it correctly to the returned list.

We can also test that inserts and updates work.
This is where @DirtiesContext comes in useful. Since we don't know the order in which the tests will be run, we don't want to leave the newly inserted 12th object in the database, if we could subsequently test that there are 11 objects in the database.

In CharityDataJDBCTests.java.

@Test
public void shouldGet12CharitiesAfterInsert() throws Exception{

        charityRepository = new CharityRepositoryJDBC(jdbcTemplate);
        Charity nspcc = charityRepository.findByAcronym("nspcc").get();

        nspcc.setId(null);
        nspcc.setAcronym("nspcc-wales");

        charityRepository.saveCharity(nspcc);

        List<Charity> charityList = charityRepository.findAll();
        assertEquals(12, charityList.size());

        nspcc = charityRepository.findByAcronym("nspcc-wales").get();

        assertEquals("nspcc", nspcc.getLogoFileName());

        }

In this example, we get a charity from the repository and then edit it so that it has no id and that the acronym is different.

As far as the repository methods are concerned, this then looks like a new charity, so when we save it, it should be inserted. So, within the scope of this test, we can check that there are 12 charities in the database and we can search for the new charity by acronym and assert that it has the expected logo file name.

Again, run the test in your preferred manner.

You should now have a suite of tests. Try running them all using Gradle > Build > build.

We've added another option to our testing toolkit. Now would be a good time to review the Testing Pyramid and try to place the different options into the layers of the pyramid.