我的@WebMvcTest 测试 类 如何在 Spring 引导中使用此 JDBC 身份验证配置进行初始化?
How can my @WebMvcTest test classes initialize with this JDBC authentication configuration in Spring Boot?
我已经将我的 Spring 引导应用程序配置为使用本地数据库进行身份验证,并且它有效(有一个警告,c.f。),但不是我的全部测试 classes 在新配置下运行良好。
这是配置的相关部分(全部查看here):
@Autowired
private DataSource dataSource;
@Override
public void configure(AuthenticationManagerBuilder builder) throws Exception {
builder .jdbcAuthentication()
.dataSource(dataSource)
.withUser(User.withUsername("admin").password(passwordEncoder().encode("pass")).roles("SUPER"));
logger.debug("Configured app to use JDBC authentication with default database.");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
用 @SpringBootTest
和 @AutoConfigureMockMvc
修饰的测试 class 有效(例如,this one)。据我了解,这些自动配置应用程序的各种 Bean 并将它们一起测试(一种集成测试形式)。
我在测试用 @WebMvcTest
修饰的 classes(例如 this one)时遇到了问题。这些应该只测试一个控制器 class 本身,对各种 Bean 和其他依赖项使用模拟对象。
- 自从实施上述配置后,他们首先开始崩溃
UnsatisfiedDependencyException
... "No qualifying bean of type 'javax.sql.DataSource' available".
- 然后我将这些行添加到每个这样的测试用例中:
@MockBean
private DataSource dataSource;
- 第一个异常似乎消失了,但现在我的日志中出现以下错误:
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection: DataSource returned null from getConnection(): javax.sql.DataSource#0 bean
这些测试在一些地方使用了 @WithMockUser
注释,预计不会使用真实的数据库或 JDBC 连接,因为它们每个都只测试一个控制器。
我的问题:如何将@WebMvcTest 与我当前的安全配置一起使用而不会使测试class失败?是否有方便的 Spring 引导注释我应该添加到测试 class 中?我是不是安全配置有误?
使测试有效的解决方案是将此 属性 添加到我的 application.yaml
:
spring:
datasource:
initialization-mode: always
或者如果您更喜欢使用 application.properties
配置文件,它看起来像这样:
spring.datasource.initialization-mode=always
感谢用户 Japan Trivedi 在我的相关问题中指出了这一点。
我已经将我的 Spring 引导应用程序配置为使用本地数据库进行身份验证,并且它有效(有一个警告,c.f。
这是配置的相关部分(全部查看here):
@Autowired
private DataSource dataSource;
@Override
public void configure(AuthenticationManagerBuilder builder) throws Exception {
builder .jdbcAuthentication()
.dataSource(dataSource)
.withUser(User.withUsername("admin").password(passwordEncoder().encode("pass")).roles("SUPER"));
logger.debug("Configured app to use JDBC authentication with default database.");
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
用 @SpringBootTest
和 @AutoConfigureMockMvc
修饰的测试 class 有效(例如,this one)。据我了解,这些自动配置应用程序的各种 Bean 并将它们一起测试(一种集成测试形式)。
我在测试用 @WebMvcTest
修饰的 classes(例如 this one)时遇到了问题。这些应该只测试一个控制器 class 本身,对各种 Bean 和其他依赖项使用模拟对象。
- 自从实施上述配置后,他们首先开始崩溃
UnsatisfiedDependencyException
... "No qualifying bean of type 'javax.sql.DataSource' available". - 然后我将这些行添加到每个这样的测试用例中:
@MockBean
private DataSource dataSource;
- 第一个异常似乎消失了,但现在我的日志中出现以下错误:
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection: DataSource returned null from getConnection(): javax.sql.DataSource#0 bean
这些测试在一些地方使用了 @WithMockUser
注释,预计不会使用真实的数据库或 JDBC 连接,因为它们每个都只测试一个控制器。
我的问题:如何将@WebMvcTest 与我当前的安全配置一起使用而不会使测试class失败?是否有方便的 Spring 引导注释我应该添加到测试 class 中?我是不是安全配置有误?
使测试有效的解决方案是将此 属性 添加到我的 application.yaml
:
spring:
datasource:
initialization-mode: always
或者如果您更喜欢使用 application.properties
配置文件,它看起来像这样:
spring.datasource.initialization-mode=always
感谢用户 Japan Trivedi 在我的相关问题中指出了这一点。