spring启动测试无法解析占位符“random.uuid”

eqqqjvef  于 2021-07-11  发布在  Java
关注(0)|答案(3)|浏览(536)

我希望spring boot属性在默认情况下具有不可能猜测的随机值(出于安全原因),因此我尝试使用随机uuid作为默认值,使用如下代码:

@Service
public class UserServiceImpl implements UserService {
...
   @Autowired
   public UserServiceImpl(@NonNull final PasswordEncoder passwordEncoder,
            @NonNull final UserRepository userRepository,
            @NonNull @Value("${administrator.password:${random.uuid}}") final String administratorPassword) {
      ...
   }

但我的 cucumber Spring 开机测试抱怨 ${random.uuid} 因此:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userServiceImpl' defined in file [.../UserServiceImpl.class]: Unexpected exception during bean creation; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'random.uuid' in value "administrator.password:${random.uuid}"

我要做什么才能让我的应用程序使用随机属性值?

a11xaf1n

a11xaf1n1#

问题可能与测试切片有关。如果我运行一个clean spring boot项目的测试:

@SpringBootTest
class DemoApplicationTests {

    @Value("${nonexistingValue:${random.uuid}}")
    private String someVal;

    @Test
    public void someTest() {
        assertThat(someVal).contains("-");
    }

}

测试通过了。但是,如果我改变 @SpringBootTest@ExtendWith({SpringExtension.class}) 或者 @RunWith(SpringRunner.class) ,测试失败。 ${random.uuid} 类似的表达式应该在正常的运行时环境中可用。
因为这个切片,看起来 RandomValuePropertySource 不可用。一个相当不雅观的解决方法是使用 PropertySourcesPlaceholderConfigurer 在测试上下文中创建的bean:

@Configuration
public class CucumberBeansConfiguration {

   @Bean
   public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
      final var configurer = new PropertySourcesPlaceholderConfigurer();
      final var sources = new MutablePropertySources();
      sources.addFirst(new RandomValuePropertySource());
      configurer.setPropertySources(sources);
      return configurer;
   }

}
6tdlim6h

6tdlim6h2#

${random.uuid} 只能在以下情况下使用 RandomValuePropertySource 是可用的。
作为解决方法,您可以定义一个“伪默认值”,并在代码中检测它:

@Autowired
   public UserServiceImpl(@NonNull final PasswordEncoder passwordEncoder,
            @NonNull final UserRepository userRepository,
            @NonNull @Value("${administrator.password:no-default-vale-provided}") final String administratorPassword) {
      this.adminPassword = "no-default-value-provided".equals(administratorPassword)
              ? UUID.randomUUID().toString()
              : administratorPassword;
   }

如果您有randomvaluepropertysource如果可用,则spel表达式${random.uuid}应该确实解析为随机uuid。${…}是属性占位符,{$…}是spel语法。
您需要更改注解:

@NonNull @Value("#{${administrator.password} ?: ${random.uuid}}") final String administratorPassword
oxalkeyp

oxalkeyp3#

cucumber 用Spring TestContextManager . 通过使用 @CucumberContextConfiguration cucumber知道使用哪个类来启动测试上下文。

import com.example.app;

import org.springframework.boot.test.context.SpringBootTest;

import io.cucumber.spring.CucumberContextConfiguration;

@CucumberContextConfiguration
@SpringBootTest
public class CucumberSpringConfiguration {

}

一定要确保 CucumberSpringConfiguration 是在 cucumber.glue 路径。

相关问题