Grails 2.4.4 integration test not using test datasource

Help!

Our plugin project integration tests should end up in the database specified in the .roovy data file, but for some reason they ignore it and do it in memory.

Its a plugin that exposes core services (i.e. database access) to multiple grails applications which are grails applications.

Datasource.groovy looks like this:

dataSource {
    pooled = true
    driverClassName = "com.mysql.jdbc.Driver"
    dialect = "org.hibernate.dialect.MySQL5InnoDBDialect"
}
environments {
    development {
        dataSource {
            dbCreate = "create-drop"
            url = "jdbc:mysql://127.0.0.1:3306/db"
            username = "someuser"
            password = "somepass"
        }
    }
    test {
        dataSource {
            dbCreate = "update"
            url = "jdbc:mysql://127.0.0.1:3306/db"
            username = "someuser"
            password = "somepass"
        }
    }
    production {
        dataSource {
        }
    }
}

      

Test (SiteIntegrationSpec.goovy)

import grails.test.mixin.TestFor
import grails.test.spock.IntegrationSpec

@TestFor(Site)
class SiteIntegrationSpec extends IntegrationSpec {
    static transactional = false

    def setup() {
    }

    def cleanup() {
    }

    void "test something"() {
        when:
        Site site
        site = new Site(name: "asdf", description: "asdfsd").save(failOnError: true)

        then:
        site.id == 3

        when:
        Site site2 = Site.get(1L)

        then:
        site2.name == "root"
    }
}

      

Data already existing in the site table: Name ID 1 root root 2 test case

The first test is to insert a record that will have ID 3. It actually inserts with ID 1, that is, it doesn't see it or hit the test database, but uses some layouts or internal db's that aren't defined anywhere.

The second test fails, instead of fetching "root", it fetching "asdf"

What I have tried:

  • creating a separate database for testing. Did not help.
  • specifying -Dgrails.env = test when running tests. Did not help
  • running tests with DB. This will fail correctly with the impossibility of throwing a type pool exception.
  • changing the password of the test data source to an invalid one - this correctly throws an exception.
  • grails -Dgrails.env = test test-app com.me.myproject.SiteIntegrationSpec --stacktrace --verbose

So grails connects to the test datasource, but then the integration tests don't use it!

Any ideas?

Edit: Site is a domain object:

class Site {
    String name
    String description
}

      

+3


source to share


1 answer


Plugin files are DataSource.groovy

not included in the plugin zip, and if you manually or programmatically enable them somehow, they will be ignored. The same applies to Config.groovy

, UrlMappings.groovy

and BootStrap.groovy

. In general, when something can be used from a plugin, if the application has a file with the same name and location, it overrides the plugin file so that it doesn't help it work.

You can define a dataSource

bean in your plugin doWithSpring

that replaces the one that grails builds from DataSource.groovy

, that uses values ​​from a file that exists in the zip plugin or in the application if it makes sense. Note that there are actually 3 DataSource beans, and two of them are "real" proxies, so you need to define yours as dataSourceUnproxied

so the other two proxies and save the behavior they add.



Another thing you will need to fix once you resolve this is the use of unit test annotations in the integration test. Never use Mock

, TestFor

or any annotation or base class unit test mixin, as their goal is to create a fairly realistic environment that takes into account Spring, Hibernate, installed plugins and a lot of Grails features, not available, but in the integration test they are available, and stuff unit test will stomp in real instances.

Also - why are you using static transactional = false

? This disables an important integration testing feature where all of your test methods are run in a transaction that is rolled back at the end of the test or fails. This ensures that nothing you do in a test affects other tests - everything is independent. If you turn this off, you need to undo all changes, and it is easy to skip some, and introduce false negatives or worse - false positives - into your tests.

+2


source







All Articles