簡體   English   中英

Spring Boot Cucumber 測試無法解析占位符“random.uuid”

[英]Spring Boot Cucumber tests could not resolve placeholder 'random.uuid'

我希望 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 Boot 測試抱怨${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}"

我該怎么做才能讓我的應用程序使用隨機屬性值?

該問題可能與測試切片有關。 如果我使用以下命令運行干凈的 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;
   }

}

${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`](https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/env/RandomValuePropertySource.html) 可用,則 SpEL 表達式 `${ random.uuid}` 確實應該解析為隨機 UUID。 `${...}` 是一個屬性占位符,`#{$...}` 是 SpEL 語法。

您需要更改注釋:

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

Cucumber 使用 Springs TestContextManager 通過使用@CucumberContextConfiguration注釋您的上下文配置,Cucumber 知道使用哪個類來啟動測試上下文。

import com.example.app;

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

import io.cucumber.spring.CucumberContextConfiguration;

@CucumberContextConfiguration
@SpringBootTest
public class CucumberSpringConfiguration {

}

確保CucumberSpringConfigurationcucumber.glue路徑上。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM