4 Multi-Tenancy Unit Testing

Testing controller logic that uses Multi-Tenancy requires special considerations.

Luckily GORM 6.1 makes it relatively simple to write unit tests.

To write a unit test for the VehicleController class create a new src/test/groovy/example/VehicleControllerSpec.groovy Spock specification:

src/test/groovy/example/VehicleControllerSpec.groovy
link:{sourcedir}/src/test/groovy/example/VehicleControllerSpec.groovy[role=include]
        ...
}

As you can see above the test extends HibernateSpec.

To make testing simpler override the tenantResolverClass by overriding the getConfiguration() method of HibernateSpec:

src/test/groovy/example/VehicleControllerSpec.groovy
link:{sourcedir}/src/test/groovy/example/VehicleControllerSpec.groovy[role=include]

This will allow you to use SystemPropertyTenantResolver for changing the tenant id within the test.

Next step is to provide a setup method that configures the VehicleService for the controller:

src/test/groovy/example/VehicleControllerSpec.groovy
link:{sourcedir}/src/test/groovy/example/VehicleControllerSpec.groovy[role=include]
1 Define a vehicleService as a property of the unit test
2 Set the tenant id to audi for the purposes of the test
3 Lookup the VehicleService implementation from GORM
4 Assign the VehicleService to the controller under test

To ensure proper cleanup you should also clear the tenant id in a cleanup method:

src/test/groovy/example/VehicleControllerSpec.groovy
link:{sourcedir}/src/test/groovy/example/VehicleControllerSpec.groovy[role=include]

With that done it is trivial to test the controller logic, for example to test the index action with no data:

src/test/groovy/example/VehicleControllerSpec.groovy
link:{sourcedir}/src/test/groovy/example/VehicleControllerSpec.groovy[role=include]

You can also write tests to test the case where no tenant id is present by clearing the tenant id:

src/test/groovy/example/VehicleControllerSpec.groovy
link:{sourcedir}/src/test/groovy/example/VehicleControllerSpec.groovy[role=include]

Testing more complex interactions like saving data is possible too:

src/test/groovy/example/VehicleControllerSpec.groovy
link:{sourcedir}/src/test/groovy/example/VehicleControllerSpec.groovy[role=include]

Note that within the assertions of the above test we use the vehicleService which makes sure the correct database connection is used when making the assertion.

  Get the Code