代码之家  ›  专栏  ›  技术社区  ›  Sai Upadhyayula

从可执行jar运行spring测试

  •  5
  • Sai Upadhyayula  · 技术社区  · 8 年前

    我有一些Spring测试,它们可以加速应用程序上下文并测试一些服务。我可以使用Maven和IDE运行这些测试。现在我需要在另一台无法访问Maven的机器上运行这些测试。我的想法是创建一个测试jar并通过命令行运行它们。

    以下是示例代码:

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

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = {AppConfig.class})
    public class SpringSampleTest {
        @Autowired
        TestService testService;
    
        @Test
        public void testSimple() {
            assertTrue("Test Simple", testService.isValid());
        }
    }
    

    这是我的配置和服务

    @Configuration
    @ComponentScan(basePackages = {"mypackage"})
    public class AppConfig {
    
    }
    
    @Service
    public class TestService {
    
        public boolean isValid() {
            return true;
        }
    }
    

    here ). 现在,当我运行这个可执行jar时,我的定制运行程序(主类)能够触发测试,但它没有加载Spring上下文,并且由于我的依赖项不是自动连接的,因此失败并出现NullPointer异常。日志如下:

    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
    

    有人能指出我做错了什么吗?

    我还添加了我的pom.xml文件和程序集描述符文件:

    <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">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>mypackage</groupId>
        <artifactId>executable-tests</artifactId>
        <version>1.0</version>
        <packaging>jar</packaging>
    
        <name>executable-tests</name>
    
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>compile</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>4.3.0.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>4.3.2.RELEASE</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.6</source>
                        <target>1.6</target>
                        <encoding>UTF-8</encoding>
                    </configuration>
                </plugin>
    
                <plugin>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <configuration>
                        <descriptor>src/main/assembly/assembly.xml</descriptor>
                    </configuration>
                    <executions>
                        <execution>
                            <id>make-assembly</id>
                            <phase>package</phase>
                            <goals>
                                <goal>assembly</goal>
                            </goals>
                            <configuration>
                                <archive>
                                    <manifest>
                                        <mainClass>mypackage.Main</mainClass>
                                    </manifest>
                                </archive>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>            
            </plugins>
        </build>
    </project>
    

    描述符-程序集.xml

    <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">
        <id>fat-tests</id>
        <formats>
            <format>jar</format>
        </formats>
        <includeBaseDirectory>false</includeBaseDirectory>
        <dependencySets>
            <dependencySet>
                <outputDirectory>/</outputDirectory>
                <useProjectArtifact>true</useProjectArtifact>
                <unpack>true</unpack>
                <scope>test</scope>
            </dependencySet>
        </dependencySets>
        <fileSets>
            <fileSet>
                <directory>${project.build.directory}/test-classes</directory>
                <outputDirectory>/</outputDirectory>
                <includes>
                    <include>**/*.class</include>
                </includes>
                <useDefaultExcludes>true</useDefaultExcludes>
            </fileSet>
        </fileSets>
    </assembly>
    

    您可以查看github中的示例项目: https://github.com/SaiUpadhyayula/executabletests

    3 回复  |  直到 8 年前
        1
  •  2
  •   CRISTIAN ROMERO MATESANZ    8 年前

    我刚从你的存储库中找到了错误。弹簧工厂必须与maven抛出测试时使用的工厂相同。必须以与测试上下文相同的方式委托到springic中。

    https://github.com/SaiUpadhyayula/executabletests/pull/2

    enter image description here

    enter image description here

    enter image description here

        2
  •  2
  •   Sai Upadhyayula    8 年前

    我在调试测试后终于发现了问题,原来Spring在引导TestContext时会查找META-INF中定义的TestExecutionListener/弹簧工厂spring测试jar中的文件。

    将此文件添加到src/main/resources/META-INF/弹簧工厂解决了这个问题

    # Default TestExecutionListeners for the Spring TestContext Framework
    #
    org.springframework.test.context.TestExecutionListener = \
        org.springframework.test.context.web.ServletTestExecutionListener,\
        org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener,\
        org.springframework.test.context.support.DependencyInjectionTestExecutionListener,\
        org.springframework.test.context.support.DirtiesContextTestExecutionListener,\
        org.springframework.test.context.transaction.TransactionalTestExecutionListener,\
        org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener
    
    # Default ContextCustomizerFactory implementations for the Spring TestContext Framework
    #
    org.springframework.test.context.ContextCustomizerFactory = \
        org.springframework.test.context.web.socket.MockServerContainerContextCustomizerFactory
    
        3
  •  -1
  •   Anand Mattikopp    8 年前

    您需要在另一台机器上安装maven来运行测试。

    如果maven安装不是一个可行的选项,那么创建一个包含测试类的jar并使用这个jar来运行测试。查看maven文档- http://maven.apache.org/plugins/maven-jar-plugin/examples/create-test-jar.html