在 ServletContext 中找不到属性 ServerContainer
Attribute ServerContainer not found in ServletContext
在我的 Spring 引导应用程序中,我还使用了 websockets。一切正常,正如生产中预期的那样。
现在我开始使用 Spring-Boot-Test 创建单元测试。
每次我启动 @SpringBootTest 时,我都会收到以下异常(缩短):
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'createWebSocketContainer' defined in class path resource [com/package/spring/ws/MyWebsocketConfig.class]: Invocation of init method failed;
Caused by: java.lang.IllegalStateException: Attribute 'javax.websocket.server.ServerContainer' not found in ServletContext
长版
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:246)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=11=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.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:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'createWebSocketContainer' defined in class path resource [com/package/spring/ws/MyWebsocketConfig.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Attribute 'javax.websocket.server.ServerContainer' not found in ServletContext
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1778)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=11=](AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:830)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:127)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)
... 24 more
Caused by: java.lang.IllegalStateException: Attribute 'javax.websocket.server.ServerContainer' not found in ServletContext
at org.springframework.util.Assert.state(Assert.java:73)
at org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean.afterPropertiesSet(ServletServerContainerFactoryBean.java:117)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774)
... 39 more
Spring Websocket 配置 Class
package com.package.spring.ws;
// removed imports
@Configuration
@EnableWebSocketMessageBroker
public class MyWebsocketConfig extends AbstractSessionWebSocketMessageBrokerConfigurer<Session> {
private final Logger logger = LogManager.getLogger(MyWebsocketConfig.class);
private int MAX_MESSAGE_SIZE = 1024 * 1024 * 16;
@Override
protected void configureStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/wss")
.setAllowedOrigins("*")
.withSockJS();
}
@Override
public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
registration.setMessageSizeLimit(MAX_MESSAGE_SIZE);
registration.setSendBufferSizeLimit(MAX_MESSAGE_SIZE);
registration.setSendTimeLimit(20000);
super.configureWebSocketTransport(registration);
}
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.setApplicationDestinationPrefixes("/app");
config.enableSimpleBroker("/queue", "/events", "/topic");
config.setCacheLimit(1024 * 10);
super.configureMessageBroker(config);
}
// This is breaking my Spring Unit Tests.
@Bean
public ServletServerContainerFactoryBean createWebSocketContainer() {
ServletServerContainerFactoryBean container = new
ServletServerContainerFactoryBean();
container.setMaxTextMessageBufferSize(MAX_MESSAGE_SIZE);
container.setMaxBinaryMessageBufferSize(MAX_MESSAGE_SIZE);
return container;
}
}
POM.XML
<?xml version="1.0" encoding="UTF-8"?>
<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>com.package</groupId>
<artifactId>MyProject</artifactId>
<version>0.8.4-RELEASE</version>
<packaging>war</packaging>
<name>My Project</name>
<description>MyProject Server</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Problem exists, with and without this websocket dependency -->
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-messaging</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Spring申请Class
package com.packge.spring;
// removed imports
@ComponentScan({"com.package.spring", "com.packe.spring.security", "com.package.endpoints"})
@EnableJpaRepositories(basePackages = "com.package.db")
@EntityScan(value = "com.package.db")
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {
@Value("my.session.cookie-name")
private String cookieName = ApplicationConfig.SESSION_COOKIE_NAME;
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
典型的失败测试
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MyApplication.class, webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class LedgerTreeMovementsTest {
@Test
public void test0_testXYZ() {
}
}
问题
问题是,实际的测试从来没有涉及到测试方法,它在设置测试应用程序时中断了。
有没有人有想法,发生了什么事?
需要更多信息吗?
非常感谢!
感谢 GSSwain,他引导我走向正确的方向,我现在能够解决我的问题。
它似乎只有在 @SpringBootTest
属性 webEnviroment
设置为 MOCK
或 NONE
时才会出现。使用定义的或随机端口告诉 Spring 加载正确的 ServletContext。
如果您不想为简单测试加载完整的上下文,有多种方法可以解决这个问题。
解决方案 1
这是大多数人需要的。添加额外的 @WebAppConfiguration
注释到您的测试 classes,它告诉 Spring 使用 ServerContainer 的模拟属性条目加载适当的 ServletContext。
解决方案 2
根据我的需要,在许多测试用例中,这仍然是很多背景膨胀,我不需要的东西。所以我在 Bean 创建本身中添加了一个检查,并添加了一个 属性 来打开或关闭检查,通过 application.properties.
在你的 WebsocketConfig class:
@Autowired
private ServletContext servletContext;
private boolean ignoreNullWsContainer;
@Bean
public ServletServerContainerFactoryBean createWebSocketContainer() {
// Check if null-container is allowed to prevent Exceptions
if (ignoreNullWsContainer) {
// Check if attribute is set in the ServletContext
ServerContainer serverContainer = (ServerContainer) this.servletContext.getAttribute("javax.websocket.server.ServerContainer");
if (serverContainer == null) {
logger.error("Could not initialize Websocket Container in Testcase.");
return null;
}
}
ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
container.setMaxTextMessageBufferSize(MAX_MESSAGE_SIZE);
container.setMaxBinaryMessageBufferSize(MAX_MESSAGE_SIZE);
return container;
}
@Value("${project.ignore-null-websocket-container:false}")
private void setIgnoreNullWsContainer(String flag) {
this.ignoreNullWsContainer = Boolean.parseBoolean(flag);
}
并且在你的 application.properties 中你的 Test src 资源目录(默认目录 src/test/resources/application.properties
project.ignoreNullWsContainer = true
这样,如果您不在生产环境 属性 文件中设置此 属性,如果 ServerContainer 出现问题,Spring 仍然会失败。
这就是我最后采用的方法,因为我不需要 Spring 测试功能,我只需要 spring 获取我的数据源配置(在属性文件中)并执行我的@Sql 注释 :D
希望这也能帮助其他人,以节省数小时的搜索、痛苦和谷歌搜索;) :)
在我的 Spring 引导应用程序中,我还使用了 websockets。一切正常,正如生产中预期的那样。
现在我开始使用 Spring-Boot-Test 创建单元测试。
每次我启动 @SpringBootTest 时,我都会收到以下异常(缩短):
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'createWebSocketContainer' defined in class path resource [com/package/spring/ws/MyWebsocketConfig.class]: Invocation of init method failed;
Caused by: java.lang.IllegalStateException: Attribute 'javax.websocket.server.ServerContainer' not found in ServletContext
长版
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:190)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:132)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:246)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access[=11=]0(ParentRunner.java:58)
at org.junit.runners.ParentRunner.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:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'createWebSocketContainer' defined in class path resource [com/package/spring/ws/MyWebsocketConfig.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Attribute 'javax.websocket.server.ServerContainer' not found in ServletContext
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1778)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=11=](AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:830)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:127)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)
... 24 more
Caused by: java.lang.IllegalStateException: Attribute 'javax.websocket.server.ServerContainer' not found in ServletContext
at org.springframework.util.Assert.state(Assert.java:73)
at org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean.afterPropertiesSet(ServletServerContainerFactoryBean.java:117)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774)
... 39 more
Spring Websocket 配置 Class
package com.package.spring.ws;
// removed imports
@Configuration
@EnableWebSocketMessageBroker
public class MyWebsocketConfig extends AbstractSessionWebSocketMessageBrokerConfigurer<Session> {
private final Logger logger = LogManager.getLogger(MyWebsocketConfig.class);
private int MAX_MESSAGE_SIZE = 1024 * 1024 * 16;
@Override
protected void configureStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/wss")
.setAllowedOrigins("*")
.withSockJS();
}
@Override
public void configureWebSocketTransport(WebSocketTransportRegistration registration) {
registration.setMessageSizeLimit(MAX_MESSAGE_SIZE);
registration.setSendBufferSizeLimit(MAX_MESSAGE_SIZE);
registration.setSendTimeLimit(20000);
super.configureWebSocketTransport(registration);
}
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.setApplicationDestinationPrefixes("/app");
config.enableSimpleBroker("/queue", "/events", "/topic");
config.setCacheLimit(1024 * 10);
super.configureMessageBroker(config);
}
// This is breaking my Spring Unit Tests.
@Bean
public ServletServerContainerFactoryBean createWebSocketContainer() {
ServletServerContainerFactoryBean container = new
ServletServerContainerFactoryBean();
container.setMaxTextMessageBufferSize(MAX_MESSAGE_SIZE);
container.setMaxBinaryMessageBufferSize(MAX_MESSAGE_SIZE);
return container;
}
}
POM.XML
<?xml version="1.0" encoding="UTF-8"?>
<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>com.package</groupId>
<artifactId>MyProject</artifactId>
<version>0.8.4-RELEASE</version>
<packaging>war</packaging>
<name>My Project</name>
<description>MyProject Server</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Problem exists, with and without this websocket dependency -->
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-messaging</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Spring申请Class
package com.packge.spring;
// removed imports
@ComponentScan({"com.package.spring", "com.packe.spring.security", "com.package.endpoints"})
@EnableJpaRepositories(basePackages = "com.package.db")
@EntityScan(value = "com.package.db")
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {
@Value("my.session.cookie-name")
private String cookieName = ApplicationConfig.SESSION_COOKIE_NAME;
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
典型的失败测试
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MyApplication.class, webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class LedgerTreeMovementsTest {
@Test
public void test0_testXYZ() {
}
}
问题
问题是,实际的测试从来没有涉及到测试方法,它在设置测试应用程序时中断了。 有没有人有想法,发生了什么事? 需要更多信息吗? 非常感谢!
感谢 GSSwain,他引导我走向正确的方向,我现在能够解决我的问题。
它似乎只有在 @SpringBootTest
属性 webEnviroment
设置为 MOCK
或 NONE
时才会出现。使用定义的或随机端口告诉 Spring 加载正确的 ServletContext。
如果您不想为简单测试加载完整的上下文,有多种方法可以解决这个问题。
解决方案 1
这是大多数人需要的。添加额外的 @WebAppConfiguration
注释到您的测试 classes,它告诉 Spring 使用 ServerContainer 的模拟属性条目加载适当的 ServletContext。
解决方案 2
根据我的需要,在许多测试用例中,这仍然是很多背景膨胀,我不需要的东西。所以我在 Bean 创建本身中添加了一个检查,并添加了一个 属性 来打开或关闭检查,通过 application.properties.
在你的 WebsocketConfig class:
@Autowired
private ServletContext servletContext;
private boolean ignoreNullWsContainer;
@Bean
public ServletServerContainerFactoryBean createWebSocketContainer() {
// Check if null-container is allowed to prevent Exceptions
if (ignoreNullWsContainer) {
// Check if attribute is set in the ServletContext
ServerContainer serverContainer = (ServerContainer) this.servletContext.getAttribute("javax.websocket.server.ServerContainer");
if (serverContainer == null) {
logger.error("Could not initialize Websocket Container in Testcase.");
return null;
}
}
ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
container.setMaxTextMessageBufferSize(MAX_MESSAGE_SIZE);
container.setMaxBinaryMessageBufferSize(MAX_MESSAGE_SIZE);
return container;
}
@Value("${project.ignore-null-websocket-container:false}")
private void setIgnoreNullWsContainer(String flag) {
this.ignoreNullWsContainer = Boolean.parseBoolean(flag);
}
并且在你的 application.properties 中你的 Test src 资源目录(默认目录 src/test/resources/application.properties
project.ignoreNullWsContainer = true
这样,如果您不在生产环境 属性 文件中设置此 属性,如果 ServerContainer 出现问题,Spring 仍然会失败。
这就是我最后采用的方法,因为我不需要 Spring 测试功能,我只需要 spring 获取我的数据源配置(在属性文件中)并执行我的@Sql 注释 :D
希望这也能帮助其他人,以节省数小时的搜索、痛苦和谷歌搜索;) :)