簡體   English   中英

SpringBoot單元測試中的模擬@Value不起作用

[英]Mock @Value in SpringBoot unit test not working

我正在嘗試使用 Mockito 進行一些 junit 測試,以便在 SprinBoot 應用程序中工作。

現在我的服務有一些變量,通過@Value注釋從application.properties中填充:

@Component
@Slf4j
public class FeatureFlagService {

  @Autowired
  RestTemplate restTemplate;

  @Value("${url.feature_flags}")
  String URL_FEATURE_FLAGS;

// do stuff
}

我正在嘗試像這樣使用TestPropertySource來測試它:

@ExtendWith(MockitoExtension.class)
@TestPropertySource(properties = { "${url.feature_flags} = http://endpoint" })
class FeatureFlagServiceTests {

  @Mock
  RestTemplate restTemplate;

  @InjectMocks
  FeatureFlagService featureFlasgService;

  @Test
  void propertyTest(){
    Assertions.assertEquals(featureFlasgService.URL_FEATURE_FLAGS, "http://endpoint");
  }

但是,該屬性未被填充並保持null

這方面有很多問題,但我無法拼湊出一個解決方案。 我看到建議@SpringBootTest的解決方案,但隨后它似乎想要進行集成測試,啟動服務,但由於無法連接到數據庫而失敗。 所以這不是我要找的。

我還看到了建議我制作PropertySourcesPlaceholderConfigurer bean 的解決方案。 我嘗試通過放置:

  @Bean
    public static PropertySourcesPlaceholderConfigurer propertiesResolver() {
    return new PropertySourcesPlaceholderConfigurer();
  }

在我的Application.java中。 但這不起作用/不夠。 我不確定我是否應該做不同的事情,或者是否還有更多我不知道的事情。

請指教。

您可以使用@SpringBootTest而無需運行整個應用程序,方法是將它傳遞給包含 @Value 的@Value但您必須使用 Spring 的擴展@ExtendWith({SpringExtension.class}) ,它包含在@SpringBootTest中,並且使用 Spring 的MockBean而不是@Mock@Autowired用於像這樣自動裝配 bean:

@SpringBootTest(classes = FeatureFlagService.class)
class FeatureFlagServiceTests {

  @MockBean
  RestTemplate restTemplate;

  @Autowired
  FeatureFlagService featureFlasgService;

  @Test
  void propertyTest(){
    Assertions.assertEquals(featureFlasgService.URL_FEATURE_FLAGS, "http://endpoint");
  }

我建議您嘗試這種方法。 只需要稍微重構並向您的FeatureFlagService添加一個包私有構造函數。

FeatureFlagService.java

@Component
@Slf4j
public class FeatureFlagService {

    private final RestTemplate restTemplate;
    private final String URL_FEATURE_FLAGS;

    // package-private constructor. test-only
    FeatureFlagService(RestTemplate restTemplate, @Value("${url.feature_flags}") String flag) {
        this.restTemplate = restTemplate;
        this.URL_FEATURE_FLAGS = flag;
    }

    // do stuff
}

然后准備你的 mocks 和 url,並通過constructor-injection注入它們。

FeatureFlagServiceTests.java

public class FeatureFlagServiceTests {

    private FeatureFlagService featureFlagService;

    @Before
    public void setup() {
        RestTemplate restTemplate = mock(RestTemplate.class);
        // when(restTemplate)...then...
        String URL_FEATURE_FLAGS = "http://endpoint";
        featureFlagService = new FeatureFlagService(restTemplate, URL_FEATURE_FLAGS);
    }

    @Test
    public void propertyTest(){
        Assertions.assertEquals(featureFlasgService.getUrlFeatureFlags(), 
        "http://endpoint");
    }
}

顯着的優勢是,您的FeatureFlagServiceTests變得非常易於閱讀和測試。 您不再需要 Mockito 的神奇注釋。

暫無
暫無

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

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