我正在使用 Spring Boot 1.4、Spock 和 spring-boot-starter-security。这是我的相关 gradle 文件:
springBootVersion = '1.4.0.BUILD-SNAPSHOT'
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-devtools')
compile('org.springframework.boot:spring-boot-starter-security')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.jasypt:jasypt-spring31:1.9.2')
compile('org.apache.httpcomponents:httpclient:4.5.2')
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile('org.spockframework:spock-core:1.1-groovy-2.4-rc-2')
testCompile('org.spockframework:spock-spring:1.1-groovy-2.4-rc-2')
我也已将其添加到我的 application-test.properties 文件中:
server.ssl.enabled=false
spring.datasource.username=test
spring.datasource.password=test
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
我能够创建一个经过身份验证的端点,该端点创建一个 JWT(使用 jasypt-spring31:1.9.2)并在授权 header 中返回它。这在通过浏览器或 Postman 访问时效果很好。但是,我无法在我的 Spring Boot 集成测试中完成这项工作。
我确实有数据库配置类,因为我的密码是加密的:
@Configuration
public class DBConfig {
@Autowired
private Environment env;
@Value("${spring.datasource.driverClassName}")
private String databaseDriverClassName;
@Value("${spring.datasource.url}")
private String datasourceUrl;
@Value("${spring.datasource.username}")
private String databaseUsername;
@Value("${jasypt.key}")
private String jasyptKey;
@Bean
public DataSource datasource() throws IOException {
return DataSourceBuilder
.create()
.username(databaseUsername)
.password(getSecurePassword())
.url(datasourceUrl)
.driverClassName(databaseDriverClassName)
.build();
}
private String getSecurePassword() throws IOException {
StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
encryptor.setPassword(jasyptKey);
Properties props = new EncryptableProperties(encryptor);
props.load(this.getClass().getClassLoader().getResourceAsStream("application-" + env.getActiveProfiles()[0] + ".properties"));
return props.getProperty("spring.datasource.password");
}
}
我的基础测试类将启动一个嵌入式 Tomcat 实例并使所有端点可用,并且有一个获取 JWT 的方法:
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@TestPropertySource("classpath:application-test.properties")
class BaseSpecification extends Specification {
@Autowired
def TestRestTemplate restTemplate
String loginAndGetJWT() {
def model = new ModelMap();
model.addAttribute("username", "ausername")
model.addAttribute("password", "apassword");
ResponseEntity<JwtAuthenticationResponse> response = restTemplate.getForEntity("/auth", String.class, model);
def jwt = response.getBody().token
return jwt;
}
}
当我尝试运行示例测试时:
class ApplicationSpecWithoutAnnotation extends BaseSpecification {
@Autowired
WebApplicationContext context
def "should boot up without errors"() {
expect: "web application context exists"
context != null
}
}
我得到以下信息:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testRestTemplate': Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: Could not initialize class org.apache.http.conn.ssl.SSLConnectionSocketFactory
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) ~[spring-beans-4.3.2.RELEASE.jar:4.3.2.RELEASE]
根据 this :只要使用 @SpringBootTest,TestRestTemplate 现在就可以作为 bean 使用。
如果我删除 compile('org.apache.httpcomponents:httpclient:4.5.2') 则错误变为:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testRestTemplate': Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/apache/http/impl/client/HttpClients
因此似乎对 Spring web 和 apache 的依赖似乎不正确。
最佳答案
事实证明,我包含的 QBO 库有违规的 http 库。我删除了对该 2.5 库的所有引用,并且我的构建已修复。不知道为什么它没有出现在我的 gradle 依赖关系树中,但是当我查看导入的 jar 时,我发现了它。
关于spring-mvc - 由于 TestRestTemplate 和 apache SSL,Spring Boot Integration 无法启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39472130/