Given a controller such as this with a simple GORM query:
@CurrentTenant
class FooController {
def list() {
[foo: Foo.list()]
}
}
And a Spock test such as this:
class FooControllerSpec
extends HibernateSpec
implements ControllerUnitTest<FooController>, DataTest {
Tenant tenant
void setupSpec() {
mockDomains Foo, Tenant
}
@Override
Map getConfiguration() {
[(Settings.SETTING_MULTI_TENANT_RESOLVER_CLASS): SystemPropertyTenantResolver]
}
def setup() {
tenant = new Tenant(name: "test").save(flush:true)
System.setProperty(SystemPropertyTenantResolver.PROPERTY_NAME, tenant.id.toString())
controller.transactionManager = transactionManager // For HibernateSpec in a controller
}
void "list"() {
when:
controller.list()
then:
response.status == 200
}
}
I would expect to be able to unit test controllers that use the @CurrentTentant
annotation.
Functionally this does work, it will only show Foo's for the current tenant, but in the unit test I get an exception:
org.grails.datastore.mapping.model.DatastoreConfigurationException: Current datastore [org.grails.datastore.mapping.simple.SimpleMapDatastore@370c9018] is not configured for Multi-Tenancy
at org.grails.datastore.gorm.services.DefaultTenantService.withCurrent(DefaultTenantService.groovy:74)
at com.foo.web.FooControllerSpec.show with no id(FooControllerSpec.groovy:39)
Is there a way to setup the current datastore for Multi-Tenancy in a unit test with a controller.
I tried to emulate the setup from this guide, but they are using @CurrentTenant on a GORM data service http://guides.grails.org/discriminator-per-tenant/guide/index.html
Solution
Part of the solution was to only use HibernateSpec, however I also had to configure the datasource as so to get the dataSource to be MultiTenant aware in my spec:
@Override
Map getConfiguration() {
[(Settings.SETTING_MULTI_TENANT_RESOLVER_CLASS): SystemPropertyLongTenantResolver,
(Settings.SETTING_MULTI_TENANCY_MODE): 'DISCRIMINATOR',
(org.grails.orm.hibernate.cfg.Settings.SETTING_DB_CREATE): "create-drop"]
}
And since our the SystemPropertyTenantResolver
can only set/get a String I had to implement my own for the test that would return a Long.
Don't implement DataTest
and change:
void setupSpec() {
mockDomains Foo, Tenant
}
to
List<Class> getDomainClasses() { [Foo, Tenant] }