Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to GrailsApplicationBuilder(or GrailsUnitTest) to conditionally load external beans (from resources.groovy) #56

Open
HugoVega opened this issue Nov 4, 2019 · 0 comments

Comments

@HugoVega
Copy link

HugoVega commented Nov 4, 2019

Grails team,

I'm currently writing unit test where I'm verifying a Camunda BPM process definition is correctly configured. The application defines multiple beans for different purposes including the multiple ones you need to make use of Camunda API declare in resources.groovy

A typical application resources.groovywould look like this:

beans = {
//Other bean deinition
 userPasswordEncoderListener(UserPasswordEncoderListener)
 authenticationEntryPoint(Http401AuthenticationEntryPoint, 'Bearer')
 logoutSuccessHandler(HttpStatusReturningLogoutSuccessHandler, HttpStatus.NO_CONTENT)
    


    //Camunda spring bean configuration
    identityProviderSessionFactory(SpringSecurityCorePluginSessionFactory)
    processEngineConfiguration(SpringProcessEngineConfiguration){
        processEngineName = "camunda-engine-${appName}-${Environment.currentEnvironment}"
        dataSource = ref("dataSource")
        databaseType = databaseUsing
        databaseSchemaUpdate = camundaSchemaStrategy
        transactionManager = ref("transactionManager")
        history = ProcessEngineConfiguration.HISTORY_DEFAULT
        jobExecutorActivate = jobExecutorEnabled
        customSessionFactories = [ref("identityProviderSessionFactory")]
    }

    processEngine(ProcessEngineFactoryBean){ bean ->
        processEngineConfiguration = ref("processEngineConfiguration")
    }

    runtimeService(processEngine: "getRuntimeService")
    taskService(processEngine: "getTaskService")
    identityService(processEngine: "getIdentityService")
    historyService(processEngine: "getHistoryService")
    formService(processEngine: "getFormService")
    managementService(processEngine: "getManagementService")
    filterService(processEngine: "getFilterService")
    externalTaskService(processEngine: "getExternalTaskService")
    caseService(processEngine: "getCaseService")
    decisionService(processEngine: "getDecisionService")
    repositoryService(processEngine: "getRepositoryService")
}

As you may see Camunda, requires a considerable amount of beans/code. Although you can create separated spring bean definition(doWithSpring(), xml, @Config ) for your unit test to declare only beans necessary for your test spec, it is better to use the same source to run the application(resources.groovy) and your test meeting with the DRY principle but the problem is that loadExternalBeanDefinion() loads all beans when for the purpose of testing, you only need to load a subset of what it is declared(in my case only Camunda Beans).

Is there any way to enhance GrailsUnitTest trait and/or GrailsApplicationBuilder class in order to enable a bean inclusion and/or exclusion Setsimilar to the plugin load feature already offered by Grails testing support?

For example:

class ProcessDefinitionSpec extends Specification implements AutowiredTest {
    Closure doWithSpring() {{ ->
        taskListener1(InstanceFactoryBean, Mock(ApprovalTaskListener))
    }}

   boolean loadExternalBeans() {true }
  
   Set<String> excludingBeans(){
        ["userPasswordEncoderListener", "authenticationEntryPoint", "logoutSuccessHandler"]. toSet()
   }

   // ALL TEST BELOW HERE
}

or using an inclusion Set:

class ProcessDefinitionSpec extends Specification implements AutowiredTest {
    Closure doWithSpring() {{ ->
        taskListener1(InstanceFactoryBean, Mock(ApprovalTaskListener))
    }}

   boolean loadExternalBeans() {true }
  
   Set<String> includinglBeans(){
      ["identityProviderSessionFactory", "processEngineConfiguration", "processEngine", "runtimeService", "taskService", "repositoryService"]. toSet()
   }

   // ALL TEST BELOW HERE
}

I hope I explain the use case well!

Saludos
Hugo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant