gpt4 book ai didi

java - 如何在 Spring 中对 Web 应用程序进行容器内测试?

转载 作者:行者123 更新时间:2023-11-28 22:37:51 25 4
gpt4 key购买 nike

首先,我是Spring的新手。

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

我知道 Arquillian 可以用嵌入式应用服务器做这类事情。但我不知道 Spring 世界中是否有等价物。如果有的话,我非常想知道。 :-)

非常感谢。

更新

经过一番谷歌搜索,我发现了一种使用嵌入式 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
}

关于上面的代码,我有一个问题是为什么 @Before 而不是 @BeforeClass。为每种测试方法启动和停止一个tomcat服务器不是很昂贵吗?另一个相关问题是,对于 @BeforeClass,tomcat 服务器是否会像 EmbeddedTomcatTestCase 类一样只创建一次?这似乎主要是一个理想的效果,但有异常(exception)吗?最重要的是,有没有比上面的代码更简单的方法?谢谢。

最佳答案

选择Spring MVC Test

The Spring MVC Test framework provides first class JUnit support for testing client and server-side Spring MVC code through a fluent API. Typically it loads the actual Spring configuration through the TestContext framework and always uses the DispatcherServlet to process requests thus approximating full integration tests without requiring a running Servlet container.

[...] Below is an example of a test requesting account information in JSON format:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("test-servlet-context.xml")
public class ExampleTests {

@Autowired
private WebApplicationContext wac;

private MockMvc mockMvc;

@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}

@Test
public void getAccount() throws Exception {
this.mockMvc.perform(get("/accounts/1").accept(MediaType.parseMediaType("application/json;charset=UTF-8")))
.andExpect(status().isOk())
.andExpect(content().contentType("application/json"))
.andExpect(jsonPath("$.name").value("Lee"));
}

}

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

测试与持久化.xml

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

如果没有 persistence.xml 就无法工作,请查看“How to configure JPA for testing in Maven”中的详尽解释。

否则请查看我的基于 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();
}
}

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

PersistenceJPAConfig.java

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

}

Spring profiles 也是可能的和测试类中的@ActiveProfile 注释和@Profile配置类或使用@Component(@Service 等)注释的类中的注释。

关于java - 如何在 Spring 中对 Web 应用程序进行容器内测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20916581/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com