title: Running spring tests from executable jar
body: <p>I have some Spring tests which spin up the application context and tests some services. I am able to run these tests using Maven and through IDE. Now I have a requirement to run these tests on the other machine where there is no access to Maven. My idea was to create a test jar and run them through the command line.</p>
  
  <p>So I created a custom Runner which invokes the test classes I need and these Tests will spin up a Spring Application context and tests some service.</p>
  
  <p>Here is the sample code: </p>
  
  <p>My Custom Runner:</p>
  
  <pre><code>public class Main {
  
      public static void main(String[] args) {
          System.out.println("Running tests!");
          JUnitCore engine = new JUnitCore();
          engine.addListener(new TextListener(System.out));
          engine.run(SpringSampleTest.class);
      }
  } 
  </code></pre>
  
  <p>The above runner is invoking this test</p>
  
  <pre><code>@RunWith(SpringJUnit4ClassRunner.class)
  @ContextConfiguration(classes = {AppConfig.class})
  public class SpringSampleTest {
      @Autowired
      TestService testService;
  
      @Test
      public void testSimple() {
          assertTrue("Test Simple", testService.isValid());
      }
  }
  </code></pre>
  
  <p>Here is my config and the Service</p>
  
  <pre><code>@Configuration
  @ComponentScan(basePackages = {"mypackage"})
  public class AppConfig {
  
  }
  
  @Service
  public class TestService {
  
      public boolean isValid() {
          return true;
      }
  }
  </code></pre>
  
  <p>So to run these tests from a jar, I have used assembly-plugin to create an executable jar which includes all my tests and dependencies(Thanks to this answer <a href="https://stackoverflow.com/a/36058365/695657">here</a> ). Now, when I am running this executable jar, My custom runner(Main.java) is able to trigger the test, but it is not loading the Spring Context and is failing with a NullPointer exception because my dependencies are not autowired. Here is the log:</p>
  
  <pre><code>Running tests!
  Sep 05, 2018 5:15:01 PM org.springframework.test.context.support.DefaultTestContextBootstrapper getDefaultTestExecutionListenerClassNames
  INFO: Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: []
  Sep 05, 2018 5:15:01 PM org.springframework.test.context.support.DefaultTestContextBootstrapper getTestExecutionListeners
  INFO: Using TestExecutionListeners: []
  .E
  Time: 0.007
  There was 1 failure:
  1) testSimple(com.c0deattack.cu.runners.SpringSampleTest)
  java.lang.NullPointerException
      at com.c0deattack.cu.runners.SpringSampleTest.testSimple(SpringSampleTest.java:19)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:498)
      at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
      at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
      at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
      at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
      at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
      at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
      at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
      at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
      at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
      at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
      at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
      at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
      at org.junit.runners.Suite.runChild(Suite.java:128)
      at org.junit.runners.Suite.runChild(Suite.java:27)
      at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
      at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
      at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
      at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
      at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
      at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
      at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
      at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
      at org.junit.runner.JUnitCore.run(JUnitCore.java:105)
      at org.junit.runner.JUnitCore.run(JUnitCore.java:94)
      at com.c0deattack.cu.runners.Main.main(Main.java:15)
  
  FAILURES!!!
  Tests run: 1,  Failures: 1
  </code></pre>
  
  <p>Can somebody please point out what I am doing wrong? </p>
  
  <p>I am also adding my pom.xml and assembly descriptor files:</p>
  
  <p>pom.xml</p>
  
  <pre><code>&lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&gt;
      &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  
      &lt;groupId&gt;mypackage&lt;/groupId&gt;
      &lt;artifactId&gt;executable-tests&lt;/artifactId&gt;
      &lt;version&gt;1.0&lt;/version&gt;
      &lt;packaging&gt;jar&lt;/packaging&gt;
  
      &lt;name&gt;executable-tests&lt;/name&gt;
  
      &lt;dependencies&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;junit&lt;/groupId&gt;
              &lt;artifactId&gt;junit&lt;/artifactId&gt;
              &lt;version&gt;4.12&lt;/version&gt;
              &lt;scope&gt;compile&lt;/scope&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework&lt;/groupId&gt;
              &lt;artifactId&gt;spring-context&lt;/artifactId&gt;
              &lt;version&gt;4.3.0.RELEASE&lt;/version&gt;
          &lt;/dependency&gt;
          &lt;dependency&gt;
              &lt;groupId&gt;org.springframework&lt;/groupId&gt;
              &lt;artifactId&gt;spring-test&lt;/artifactId&gt;
              &lt;version&gt;4.3.2.RELEASE&lt;/version&gt;
              &lt;scope&gt;test&lt;/scope&gt;
          &lt;/dependency&gt;
      &lt;/dependencies&gt;
  
      &lt;build&gt;
          &lt;plugins&gt;
              &lt;plugin&gt;
                  &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                  &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
                  &lt;configuration&gt;
                      &lt;source&gt;1.6&lt;/source&gt;
                      &lt;target&gt;1.6&lt;/target&gt;
                      &lt;encoding&gt;UTF-8&lt;/encoding&gt;
                  &lt;/configuration&gt;
              &lt;/plugin&gt;
  
              &lt;plugin&gt;
                  &lt;artifactId&gt;maven-assembly-plugin&lt;/artifactId&gt;
                  &lt;configuration&gt;
                      &lt;descriptor&gt;src/main/assembly/assembly.xml&lt;/descriptor&gt;
                  &lt;/configuration&gt;
                  &lt;executions&gt;
                      &lt;execution&gt;
                          &lt;id&gt;make-assembly&lt;/id&gt;
                          &lt;phase&gt;package&lt;/phase&gt;
                          &lt;goals&gt;
                              &lt;goal&gt;assembly&lt;/goal&gt;
                          &lt;/goals&gt;
                          &lt;configuration&gt;
                              &lt;archive&gt;
                                  &lt;manifest&gt;
                                      &lt;mainClass&gt;mypackage.Main&lt;/mainClass&gt;
                                  &lt;/manifest&gt;
                              &lt;/archive&gt;
                          &lt;/configuration&gt;
                      &lt;/execution&gt;
                  &lt;/executions&gt;
              &lt;/plugin&gt;            
          &lt;/plugins&gt;
      &lt;/build&gt;
  &lt;/project&gt;
  </code></pre>
  
  <p>descriptor - assembly.xml</p>
  
  <pre><code>&lt;assembly
          xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd"&gt;
      &lt;id&gt;fat-tests&lt;/id&gt;
      &lt;formats&gt;
          &lt;format&gt;jar&lt;/format&gt;
      &lt;/formats&gt;
      &lt;includeBaseDirectory&gt;false&lt;/includeBaseDirectory&gt;
      &lt;dependencySets&gt;
          &lt;dependencySet&gt;
              &lt;outputDirectory&gt;/&lt;/outputDirectory&gt;
              &lt;useProjectArtifact&gt;true&lt;/useProjectArtifact&gt;
              &lt;unpack&gt;true&lt;/unpack&gt;
              &lt;scope&gt;test&lt;/scope&gt;
          &lt;/dependencySet&gt;
      &lt;/dependencySets&gt;
      &lt;fileSets&gt;
          &lt;fileSet&gt;
              &lt;directory&gt;${project.build.directory}/test-classes&lt;/directory&gt;
              &lt;outputDirectory&gt;/&lt;/outputDirectory&gt;
              &lt;includes&gt;
                  &lt;include&gt;**/*.class&lt;/include&gt;
              &lt;/includes&gt;
              &lt;useDefaultExcludes&gt;true&lt;/useDefaultExcludes&gt;
          &lt;/fileSet&gt;
      &lt;/fileSets&gt;
  &lt;/assembly&gt;
  </code></pre>
  
  <p>You can have a look at the sample project in github : <a href="https://github.com/SaiUpadhyayula/executabletests" rel="noreferrer">https://github.com/SaiUpadhyayula/executabletests</a></p>