为什么在 运行 mvn test 时 spring-boot 没有获取我的测试属性

Why aren't my test properties getting picked up by spring-boot when running mvn test

我们有一个基于 Spring-boot 2 的 Web 应用程序。0.x - 最近为 OAuth2 启用了 Spring-security - 安全有效,但我正在处理善后事宜在我的项目中。由于未满足的异常错误,我现有的测试用例失败了 - 无法弄清楚原因。请帮助。我不知道为什么它无法解析这些 属性 占位符中的任何一个:w3.clientId、w3.clientSecret 等 - 我在主文件的 application.properties 文件中都有它们路径和测试路径。见下文。

这里是主要的应用class定义:

package com.ibm.cio.cloud.cost.spreadsheet;
@SpringBootApplication
@ComponentScan({"com.ibm.cio.cloud.cost.spreadsheet","com.ibm.cio.cloud.cost.spreadsheet.rest.controller","com.ibm.cio.cloud.cost.spreadsheet.dao", "com.ibm.cio.cloud.cost.spreadsheet.service"})
public class BlueCostSpreadsheetUploadWebApplication {

    public static void main(String[] args) {
        System.setProperty("spring.devtools.restart.enabled", "false");
        SpringApplication.run(BlueCostSpreadsheetUploadWebApplication.class, args);
    }

}

这是我的测试用例定义: 包裹 com.ibm.cio.cloud.cost.spreadsheet.dao;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=BlueCostSpreadsheetUploadWebApplication.class)
public class UTCostSpreadsheetDAOTest {

    @Autowired
    private JdbcTemplate jdbcTemplate;

这是导致问题的 W3OpenIdConnectConfig class:

package com.ibm.cio.cloud.cost.spreadsheet.security;

@Configuration
@EnableOAuth2Client
public class W3OpenIdConnectConfig {
@Value("${w3.clientId}")
private String clientId;

@Value("${w3.clientSecret}")
private String clientSecret;

@Value("${w3.accessTokenUri}")
private String accessTokenUri;

@Value("${w3.userAuthorizationUri}")
private String userAuthorizationUri;

@Value("${w3.redirectUri}")
private String redirectUri;

@Bean
public OAuth2ProtectedResourceDetails w3OpenId() {

最后,这是我的 src/test/resources/application.properties 文件:

spring.servlet.multipart.max-file-size=5MB
spring.servlet.multipart.max-request-size=5MB
spring.http.multipart.enabled=false


w3.clientId=ZjgzMTM3NT222NC00
w3.clientSecret=NTdmM2IyZD333iMi00
w3.accessTokenUri=https://w3id-test.sso.ibm.com/isam/oidc/endpoint/amapp-runtime-oidcidp/token
w3.userAuthorizationUri=https://w3id-test.sso.ibm.com/isam/oidc/endpoint/amapp-runtime-oidcidp/authorize
w3.redirectUri=https://localhost:8443/auth/sso/callback
w3.issuer=https://w3id-test.sso.ibm.com/isam

rsa.key=-----BEGIN PUBLIC KEY-----MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAodx954SU1L12SOoRH7pLhB+4S/9mLkVOMt/tyhf3TZ1TUlNRroPxLtMtVjh5LL1LlCW8XxnqbGnGc0EJamRZ3eMFpn/keJbSW6T9m+pTzY/VxUWuf4uJBDzfggOXIv+VLJ/SsPPeNKZAcriIGKG5chw6Fy9FYkk91RN2/VYoysiAqof0aXYzsbxiFbUdTFFk0CAwEAAQ==-----END PUBLIC KEY-----

# Users not allowed unless part of this bluegroup
authorized.bluegroup=BLUECOST_SPREADSHEET_UPLOAD

这是我使用 'mvn test -Dtest=UTCostSpreadsheetDAOTest' 从 cmd 行 运行 单个测试用例时出现的错误:

[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.ibm.cio.cloud.cost.spreadsheet.dao.UTCostSpreadsheetDAOTest
11:19:15,034 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml]
11:19:15,035 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy]
11:19:15,035 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/C:/BlueCostSpreadsheetUploadWeb/backend/target/classes/logback.xml]
11:19:15,038 |-WARN in ch.qos.logback.classic.LoggerContext[default] - Resource [logback.xml] occurs multiple times on the classpath.
11:19:15,038 |-WARN in ch.qos.logback.classic.LoggerContext[default] - Resource [logback.xml] occurs at [file:/C:/BlueCostSpreadsheetUploadWeb/backend/target/classes/logback.xml]
11:19:15,038 |-WARN in ch.qos.logback.classic.LoggerContext[default] - Resource [logback.xml] occurs at [jar:file:/C:/Users/JamesDePaul/.m2/repository/net/sourceforge/cobertura/cobertura/2.1.1/cobertura-2.1.1.jar!/logback.xml]
11:19:15,318 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set
11:19:15,321 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender]
11:19:15,355 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT]
11:19:15,592 |-WARN in ch.qos.logback.core.ConsoleAppender[STDOUT] - This appender no longer admits a layout as a sub-component, set an encoder instead.
11:19:15,592 |-WARN in ch.qos.logback.core.ConsoleAppender[STDOUT] - To ensure compatibility, wrapping your layout in LayoutWrappingEncoder.
11:19:15,592 |-WARN in ch.qos.logback.core.ConsoleAppender[STDOUT] - See also http://logback.qos.ch/codes.html#layoutInsteadOfEncoder for details
11:19:15,602 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.springframework.security.oauth2] to INFO
11:19:15,602 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [org.springframework.security.oauth2] to true
11:19:15,602 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[org.springframework.security.oauth2]
11:19:15,604 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to ERROR
11:19:15,604 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT]
11:19:15,605 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to DEBUG
11:19:15,605 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT]
11:19:15,605 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to INFO
11:19:15,605 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT]
11:19:15,605 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration.
11:19:15,607 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@588cd519 - Registering current configuration as safe fallback point

2018-09-14 11:19:16 INFO  o.s.t.c.s.DefaultTestContextBootstrapper - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener, org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener, org.springframework.security.test.context.support.ReactorContextTestExecutionListener]
2018-09-14 11:19:16 INFO  o.s.t.c.s.DefaultTestContextBootstrapper - Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@16134476, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@62b09715, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@3e214105, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@da4cf09, org.springframework.test.context.support.DirtiesContextTestExecutionListener@1980a3f, org.springframework.test.context.transaction.TransactionalTestExecutionListener@67f63d26, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@536b71b4, org.springframework.security.test.context.support.WithSecurityContextTestExecutionListener@789c3057, org.springframework.security.test.context.support.ReactorContextTestExecutionListener@39941489, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@6f5d0190, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@67332b1e, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@7e34b127, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@679dd234, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@60cb1ed6]
2018-09-14 11:19:17 INFO  o.s.c.s.GenericApplicationContext - Refreshing org.springframework.context.support.GenericApplicationContext@1cb9ef52: startup date [Fri Sep 14 11:19:17 MDT 2018]; root of context hierarchy
2018-09-14 11:19:25 INFO  o.s.c.s.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$e373773] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2018-09-14 11:19:28 INFO  o.f.c.internal.util.VersionPrinter - Flyway Community Edition 5.0.7 by Boxfuse
2018-09-14 11:19:28 INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
2018-09-14 11:19:28 WARN  c.z.hikari.util.DriverDataSource - Registered driver with driverClassName=org.hsqldb.jdbcDriver was not found, trying direct instantiation.
2018-09-14 11:19:30 INFO  com.zaxxer.hikari.pool.PoolBase - HikariPool-1 - Driver does not support get/set network timeout for connections. (feature not supported)
2018-09-14 11:19:30 INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
2018-09-14 11:19:30 INFO  o.f.c.i.database.DatabaseFactory - Database: jdbc:hsqldb:mem:testdb (HSQL Database Engine 2.4)
2018-09-14 11:19:31 INFO  o.f.core.internal.command.DbValidate - Successfully validated 3 migrations (execution time 00:00.304s)
2018-09-14 11:19:31 INFO  o.f.c.i.s.JdbcTableSchemaHistory - Creating Schema History table: "PUBLIC"."flyway_schema_history"
2018-09-14 11:19:31 INFO  o.f.core.internal.command.DbMigrate - Current version of schema "PUBLIC": << Empty Schema >>
2018-09-14 11:19:31 INFO  o.f.core.internal.command.DbMigrate - Migrating schema "PUBLIC" to version 1 - Create BLUE COST SSCDATA Table
2018-09-14 11:19:31 INFO  o.f.core.internal.command.DbMigrate - Migrating schema "PUBLIC" to version 1.1 - Create COST SPREADSHEET Table
2018-09-14 11:19:31 INFO  o.f.core.internal.command.DbMigrate - Migrating schema "PUBLIC" to version 1.2 - ALTER COST SPREADSHEET Table ADD  FILENAME
2018-09-14 11:19:31 INFO  o.f.core.internal.command.DbMigrate - Successfully applied 3 migrations to schema "PUBLIC" (execution time 00:00.512s)
2018-09-14 11:19:32 WARN  o.s.c.s.GenericApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfig': Unsatisfied dependency expressed through field 'restTemplate'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'w3OpenIdConnectConfig': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'w3.clientId' in value "${w3.clientId}"
2018-09-14 11:19:32 INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
2018-09-14 11:19:32 INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
2018-09-14 11:19:32 ERROR o.s.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@da4cf09] to prepare test instance [com.ibm.cio.cloud.cost.spreadsheet.dao.UTCostSpreadsheetDAOTest@2298e5d2]
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.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
        at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
        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[=16=]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.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:369)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:275)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:239)
        at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:160)
        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:373)
        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:334)
        at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:119)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:407)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfig': Unsatisfied dependency expressed through field 'restTemplate'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'w3OpenIdConnectConfig': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'w3.clientId' in value "${w3.clientId}"
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586)
        at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91)
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:372)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1341)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:572)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=16=](AbstractBeanFactory.java:317)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:759)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:869)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
        at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:128)
        at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
        at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:107)
        at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:243)
        at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
        at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)

我通过在我的测试用例上添加以下注释解决了这个问题 class:

@RunWith(SpringJUnit4ClassRunner.class)
@TestPropertySource(locations = "classpath:application.properties")
@WebAppConfiguration
@ContextConfiguration(classes=BlueCostSpreadsheetUploadWebApplication.class)
public class UTCostSpreadsheetDAOTest {