Search code examples
spockmicronautmicronaut-data

MicronautTest Datasource setup not clean before each execution


I have this micronaut application doing some basic database lookup, just for testing the framework. I have setup the application with flyway database migrations, running a h2 database in my test setup (production uses postgresql). This is used for setting up the schema correctly.

My repository is created using Micronaut data for jpa, so I do not know how to create it without running the tests in full micronaut context.

In my test I try to insert some data in the setup method, before executing some spock tests. When the setup has run once, I would expect it to start with a clean datasource for the next test execution. Since the data will violate a unique constraint, it fails with an sql error in setup for the second test being run. Here's my code:

@MicronautTest()
class CompanyRepositoryTest extends Specification {

    @Inject
    CompanyRepository repository
    @Inject
    DataSource dataSource

    def sql

    def setup() {
        sql = new Sql(dataSource: dataSource)
        sql.execute(dataSql)
    }

    def 'test company creation' () {
        given:
            def name = 'test2'
            def orgNumber = '1232429045'
        when:
            def company = repository.save(new Company(name: name, organizationNumber: orgNumber))
        then:
            company.id != null
    }

    @Unroll
    def 'get company for #desc'() {
        when:
            Company result = repository.find(id)
        then:
            name == null ? result == null : name == result.name
        where:
            id | name    | desc
            1  | 'test1' | 'existing company'
            2  | null    | 'non-existing company'
    }

    def dataSql = """
            insert into company(name, organization_number) values
            ('test1', '1232429045');
            """

I guess I could create a cleanup block where I execute delete statements, but I see that as a last resort as I would expect the datasource to be clean before each test run.


Solution

  • After a good nights sleep, the obvious answer came to me. Instead of executing the sql through groovy sql,I use entitymanager. Then this works as expected

        @Inject
        EntityManager entityManager
    
        def setup() {
            entityManager.createNativeQuery(dataSql).executeUpdate();
        }