测试使用@CurrentTenant

时间:2017-08-29 01:28:02

标签: grails gorm

给定一个带有简单GORM查询的控制器:

@CurrentTenant
class FooController {
    def list() {
        [foo: Foo.list()]
    }
}

这样的Spock测试:

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
    }
}

我希望能够使用@CurrentTentant注释的单元测试控制器。

功能上这确实有用,它只会显示当前租户的Foo,但在单元测试中我得到一个例外:

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)

有没有办法在使用控制器的单元测试中为多租户设置当前数据存储区。

我尝试模拟本指南中的设置,但他们在GORM数据服务上使用@CurrentTenant http://guides.grails.org/discriminator-per-tenant/guide/index.html

解决方案

部分解决方案是仅使用HibernateSpec,但我还必须配置数据源,以便在我的规范中使dataTource成为MultiTenant:

@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"]
}

由于我们的SystemPropertyTenantResolver只能设置/获取一个字符串,我必须实现自己的测试才能返回Long。

1 个答案:

答案 0 :(得分:0)

Don't implement wordpress and change:

<md-sidenav-container fullscreen> 
  <md-sidenav>
    <router-outlet name="sidenav"></router-outlet>
  </md-sidenav>
  <div class="app">
    <main>
      <router-outlet></router-outlet>
    </main>
  </div>
</md-sidenav-container>

to

<a [routerLink]="[{ outlets: { 'sidenav': ['sidenav-component1'] } }]">
  Click to apply new sidenav.
</a>