title: Grails 3: Custom Application class for integration tests
body: <p>I want to customize the Application class that's used for integration tests. According to the user guide, this should be possible:</p>
  
  <blockquote>
    <p>The Integration annotation supports an optional applicationClass attribute which may be used to specify the application class to use for the functional test. The class must extend GrailsAutoConfiguration.</p>
  </blockquote>
  
  <p>(from <a href="http://grails.github.io/grails-doc/3.0.x/guide/testing.html#integrationTesting" rel="noreferrer">http://grails.github.io/grails-doc/3.0.x/guide/testing.html#integrationTesting</a>)</p>
  
  <p>So my integration test is annotated with </p>
  
  <pre><code>@Integration(applicationClass = TestApplication)
  class DataServiceSpec extends Specification {
  </code></pre>
  
  <p>The test application class (not yet customized) looks like:</p>
  
  <pre><code>class TestApplication extends GrailsAutoConfiguration {
  }
  </code></pre>
  
  <p>Running the integration test (with either grails test-app or gradle integrationTest results in an ApplicationContextException with root cause of a missing EmbeddedServletContainerFactory.
  Is this a bug, or do I use the applicationClass attribute wrongly? Where should such a customized application class reside? I got the same error when I put it within the integration-test sources and within grails-app/init.
  Or is there another way to add another @Configuration class to the integration test context?</p>
  
  <p>Here's the full stack trace:</p>
  
  <pre><code>java.lang.IllegalStateException: Failed to load ApplicationContext
      at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:94)
      at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72)
      at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
      at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
      at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
      at org.spockframework.spring.SpringTestContextManager.prepareTestInstance(SpringTestContextManager.java:49)
      at org.spockframework.spring.SpringInterceptor.interceptSetupMethod(SpringInterceptor.java:42)
      at org.spockframework.runtime.extension.AbstractMethodInterceptor.intercept(AbstractMethodInterceptor.java:28)
      at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:87)
      at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:86)
      at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:49)
      at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:64)
      at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:50)
      at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
      at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
      at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
      at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
      at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:106)
      at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
      at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
      at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:360)
      at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
      at java.lang.Thread.run(Thread.java:745)
  Caused by: org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
      at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:133)
      at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:474)
      at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
      at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
      at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
      at grails.boot.GrailsApp.run(GrailsApp.groovy:49)
      at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:101)
      at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:68)
      at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86)
      ... 24 more
  Caused by: org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
      at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:183)
      at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:156)
      at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:130)
      ... 32 more
  </code></pre>