grails / grails-data-mapping

GORM - Groovy Object Mapping
http://gorm.grails.org/
217 stars 198 forks source link

Best Practice for mocking Tenants API in unit tests for multi tenant applications #849

Open bleurubin opened 7 years ago

bleurubin commented 7 years ago

Is there an easy mechanism for mocking the Tenants API in unit tests for a multi tenant application?

With my application configured for DISCRIMINATOR mode multi tenancy, I get an error without doing metaprogramming on the Tenants class. In FooSpec below, if I don't specify the:

Tenants.metaClass.static.currentId = { "test" }

in the setup method, I receive the error:

Datastore implementation does not support multi-tenancy
java.lang.UnsupportedOperationException: Datastore implementation does not support multi-tenancy
    at grails.gorm.multitenancy.Tenants.currentId(Tenants.groovy:62)
    at multitenantsample.Foo.<init>(Foo.groovy:10)
    at multitenantsample.FooSpec.test save foo(FooSpec.groovy:20)

This is reasonably straightforward for mocking the currentId() method, but methods like withCurrent, eachTenant, or withId seem like they will be fairly complex to mock.

Also, is there a way to get the String tenantId = Tenants.currentId() functionality automatically, so that the tenantId defaults to the currentId whenever I create a new Foo?

Foo DO:

class Foo implements MultiTenant<Foo> {

    String tenantId = Tenants.currentId()
    String name

    static constraints = {
        name unique: true
    }
}

FooSpec:

@TestMixin(GrailsUnitTestMixin)
@Mock([Foo])
class FooSpec extends Specification {

    def setup() {
        Tenants.metaClass.static.currentId = { "test" }
    }

    void "test save foo"() {
        given:
        new Foo(name: 'foo1').save(flush: true, failOnError: true)

        expect:
        Foo.count == 1
    }
}
graemerocher commented 7 years ago

Currently the in-memory map implementation for unit testing does not support multi-tenancy. You can however use HibernateSpec or MongoSpec or Neo4jSpec to test your multi tenant domain models