Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Spring中对web应用程序进行容器内测试?_Java_Spring_Tomcat_Spring Mvc_Jboss Arquillian - Fatal编程技术网

Java 如何在Spring中对web应用程序进行容器内测试?

Java 如何在Spring中对web应用程序进行容器内测试?,java,spring,tomcat,spring-mvc,jboss-arquillian,Java,Spring,Tomcat,Spring Mvc,Jboss Arquillian,首先,我是春天的新手 假设您正在开发一个web应用程序,并且希望对http请求进行容器内功能测试,该请求应该得到字符串“Hello,World!”的响应。例如,假设web应用程序将部署到Tomcat。我想要实现的是:当测试开始时,应用程序将被部署到某种嵌入式Tomcat上。然后,您可以使用HTTP客户端(例如,Jersey客户端)发送请求并测试响应 我知道Arquillian可以用嵌入式应用服务器做这类事情。但我不知道在春天的世界里是否有类似的东西。如果有,我很想知道。:-) 多谢各位 更新 通

首先,我是春天的新手

假设您正在开发一个web应用程序,并且希望对http请求进行容器内功能测试,该请求应该得到字符串“Hello,World!”的响应。例如,假设web应用程序将部署到Tomcat。我想要实现的是:当测试开始时,应用程序将被部署到某种嵌入式Tomcat上。然后,您可以使用HTTP客户端(例如,Jersey客户端)发送请求并测试响应

我知道Arquillian可以用嵌入式应用服务器做这类事情。但我不知道在春天的世界里是否有类似的东西。如果有,我很想知道。:-)

多谢各位

更新

通过谷歌搜索,我发现了一种使用嵌入式Tomcat进行测试的模式,如下所示:

// EmbeddedTomcatTestCase.java
public abstract class EmbeddedTomcatTestCase {
    private Tomcat tomcat;

    @Before
    public void setup() {
        this.tomcat = new Tomcat();
        // setup steps go here

        this.tomcat.start();
        this.tomcat.getServer().await();
    }

    @After
    public void teardown() {
        this.tomcat.stop();
    }
}

// ConcreteTest.java
public class ConcreteTest extends EmbeddedTomcatTestCase {
    // tests go here
}
关于上面的代码,我有一个问题,为什么
@在
之前,而不是
@在课前
。对于每种测试方法,启动和停止tomcat服务器不是很昂贵吗?另一个相关问题是,对于
@BeforeClass
,tomcat服务器是否会像EmbeddedTomcatTestCase类一样只创建一次?这似乎是一个理想的效果,但有例外吗?最重要的是,有没有比上面的代码更简单的方法?谢谢。

一起去吧

SpringMVC测试框架通过一个流畅的API为测试客户端和服务器端SpringMVC代码提供了一流的JUnit支持。通常,它通过TestContext框架加载实际的Spring配置,并始终使用DispatcherServlet来处理请求,从而近似于完全集成测试,而不需要运行Servlet容器

以下[…]是一个以JSON格式请求帐户信息的测试示例:

SpringMVC测试并不区分与SpringMVC相关的组件和您自己的组件类。 Spring加载并配置它在Spring配置中可以找到的每个bean,包括持久层类

Testing和persistence.xml 在基于spring的应用程序中,您可以在生产和测试代码中完全省略persistence.xml

如果没有persistence.xml就无法工作,请查看在“”中完成的这些详尽解释

另外,看看我的基于java的最低配置,它没有persistence.xml 并根据需要从src/main/resources或src/test/resources加载config.properties 您是否正在运行测试(在基于xml的配置中也可以这样做,为了简洁起见跳过)

AppConfig.java

package config;

import org.springframework.context.annotation.*;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@ComponentScan(basePackages = { "myapp" })
@EnableTransactionManagement
@Import(PersistenceJPAConfig.class)
public class AppConfig {

    //this bean has to be in the application context if you use property files
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
    return new PropertySourcesPlaceholderConfigurer();
    }
}
package config;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@PropertySource("classpath:config.properties")
@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig {

    @Value("${driverClass}")
    private String driverClassName;

    @Value("${url}")
    private String url;

    private boolean jpaGenerateDdl = true;

    @Value("${dialect}")
    private String hibernateDialect;

    @Value("${db.username}")
    private String username;

    @Value("${db.password}")
    private String password;

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
    final LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
    factoryBean.setDataSource(dataSource());
    factoryBean.setPackagesToScan(new String[] { "entities" }); //package wir your annotated jpa entities

    final JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter() {{
            setDatabasePlatform(hibernateDialect);
            setGenerateDdl(jpaGenerateDdl);
        }
    };
    factoryBean.setJpaVendorAdapter(vendorAdapter);

    return factoryBean;
    }

    @Bean
    public DataSource dataSource() {
    final DriverManagerDataSource dataSource = new DriverManagerDataSource();

    dataSource.setDriverClassName(driverClassName);
    dataSource.setUrl(url);
    dataSource.setUsername(username);
    dataSource.setPassword(password);

    return dataSource;
    }

    @Bean
    public JpaTransactionManager transactionManager() {
    final JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());

    return transactionManager;
    }

}
JPA配置有一个单独的配置类:

PersistenceJPAConfig.java

package config;

import org.springframework.context.annotation.*;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@ComponentScan(basePackages = { "myapp" })
@EnableTransactionManagement
@Import(PersistenceJPAConfig.class)
public class AppConfig {

    //this bean has to be in the application context if you use property files
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
    return new PropertySourcesPlaceholderConfigurer();
    }
}
package config;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@PropertySource("classpath:config.properties")
@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig {

    @Value("${driverClass}")
    private String driverClassName;

    @Value("${url}")
    private String url;

    private boolean jpaGenerateDdl = true;

    @Value("${dialect}")
    private String hibernateDialect;

    @Value("${db.username}")
    private String username;

    @Value("${db.password}")
    private String password;

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
    final LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
    factoryBean.setDataSource(dataSource());
    factoryBean.setPackagesToScan(new String[] { "entities" }); //package wir your annotated jpa entities

    final JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter() {{
            setDatabasePlatform(hibernateDialect);
            setGenerateDdl(jpaGenerateDdl);
        }
    };
    factoryBean.setJpaVendorAdapter(vendorAdapter);

    return factoryBean;
    }

    @Bean
    public DataSource dataSource() {
    final DriverManagerDataSource dataSource = new DriverManagerDataSource();

    dataSource.setDriverClassName(driverClassName);
    dataSource.setUrl(url);
    dataSource.setUsername(username);
    dataSource.setPassword(password);

    return dataSource;
    }

    @Bean
    public JpaTransactionManager transactionManager() {
    final JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());

    return transactionManager;
    }

}

测试类中的和@ActiveProfile注释以及配置类中的注释或用@Component(@Service等)注释的类也可以实现同样的效果。

为了更好地理解用例,您正在运行什么类型的测试

作为使用嵌入式tomcat进行集成测试的替代方法,请看一下在集成测试阶段运行完整标准tomcat的方法,以及这样一个工具,它可以向服务器发送请求并生成测试报告结果

此解决方案将只启动tomcat容器一次

完整容器测试通常仅对性能度量测试或完全自动化的GUI测试(如使用从浏览器运行的selenium宏)是必需的,在其他集成测试中,Spring test MVC是最好的方法

如果这适合用例,这是一个maven配置的示例,用于启动tomcat、运行集成测试(在本例中是一些性能测试)并生成测试报告的概要文件

这将适用于任何技术堆栈,而不仅仅是Spring或Seam:

 <profiles>
        <profile>
            <id>performance-tests</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.codehaus.mojo</groupId>
                        <artifactId>properties-maven-plugin</artifactId>
                        <version>1.0-alpha-2</version>
                        <executions>
                            <execution>
                                <phase>initialize</phase>
                                <goals>
                                    <goal>read-project-properties</goal>
                                </goals>
                                <configuration>
                                    <files>
                                        <file>${basedir}/performance-tests/performance-tests.properties</file>
                                    </files>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                    <plugin>
                        <groupId>org.codehaus.cargo</groupId>
                        <artifactId>cargo-maven2-plugin</artifactId>
                        <configuration>
                            <container>
                                <containerId>tomcat6x</containerId>
                                <home>${basedir}/performance-tests/tomcat6-install</home>
                            </container>
                            <configuration>
                                <properties>
                                    <cargo.servlet.port>443</cargo.servlet.port>
                                    <cargo.protocol>https</cargo.protocol>
                                    <cargo.tomcat.connector.clientAuth>false</cargo.tomcat.connector.clientAuth>
                                    <cargo.tomcat.connector.sslProtocol>TLS</cargo.tomcat.connector.sslProtocol>
                                    <cargo.tomcat.connector.keystoreFile>${basedir}/tomcat/keystore.jks</cargo.tomcat.connector.keystoreFile>
                                    <cargo.tomcat.connector.keystorePass>secret</cargo.tomcat.connector.keystorePass>
                                    <cargo.tomcat.httpSecure>true</cargo.tomcat.httpSecure>
                                    <cargo.datasource.datasource.ds1>
                                        cargo.datasource.url=${perf.test.datasource.url}|
                                        cargo.datasource.driver=${perf.test.datasource.driver}|
                                        cargo.datasource.username=${perf.test.datasource.username}|
                                        cargo.datasource.password=${perf.test.datasource.password}|
                                        cargo.datasource.type=${perf.test.datasource.type}|
                                        cargo.datasource.jndi=${perf.test.ds1.jndi.name}
                                    </cargo.datasource.datasource.ds1>

                                </properties>
                            </configuration>
                        </configuration>
                        <executions>
                            <execution>
                                <id>start-container</id>
                                <phase>pre-integration-test</phase>
                                <goals>
                                    <goal>start</goal>
                                </goals>
                            </execution>
                            <execution>
                                <id>stop-container</id>
                                <phase>post-integration-test</phase>
                                <goals>
                                    <goal>stop</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                    <plugin>
                        <groupId>org.codehaus.mojo</groupId>
                        <artifactId>chronos-jmeter-maven-plugin</artifactId>
                        <version>1.1.0</version>
                        <configuration>
                            <input>${basedir}/performance-tests/mobile-gateway-performance-tests.jmx</input>
                            <jmeterhome>${basedir}/performance-tests/jmeter</jmeterhome>
                        </configuration>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>jmeter</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
            <reporting>
                <plugins>
                    <plugin>
                        <groupId>org.codehaus.mojo</groupId>
                        <artifactId>chronos-report-maven-plugin</artifactId>
                        <version>1.1.0</version>
                    </plugin>
                </plugins>
            </reporting>
        </profile>
    </profiles>

性能测试
org.codehaus.mojo
属性maven插件
1.0-α-2
初始化
读取项目属性
${basedir}/performance tests/performance-tests.properties
org.codehaus.cargo
cargo-maven2-plugin
tomcat6x
${basedir}/performance tests/tomcat6安装
443
https
假的
TLS
${basedir}/tomcat/keystore.jks
秘密
真的
cargo.datasource.url=${perf.test.datasource.url}|
cargo.datasource.driver=${perf.test.datasource.driver}|
cargo.datasource.username=${perf.test.datasource.username}|
cargo.datasource.password=${perf.test.datasource.password}|
cargo.datasource.type=${perf.test.datasource.type}|
cargo.datasource.jndi=${perf.test.ds1.jndi.name}