是否可以在不自动装配被测 class 的情况下从 application.properties 检索值?

Is it possible to retrieve value from application.properties without autowiring the class under test?

我有一个测试 class,它用 @Spy@InjectMocks 注释并使用 Mockito 进行了测试。测试中的 class 有一个从 application.properties 文件中检索到的值 (url)。我想测试这个 url 是否在使用它的方法中被正确设置。如果我删除 @Spy@InjectMocks 注释并使用 @Autowire@SpringBootTest,我就可以做到这一点。但是,这会破坏其他使用间谍功能的测试,所以我想知道是否有任何方法可以让间谍继续工作并在同一个文件中测试我们所有的方法,也许不需要引入 @SpringBootTest 注释和自动装配?我们现在使用的解决方法是有两个文件,一个使用间谍,另一个测试使用属性文件的特定方法,并且需要加载完整的上下文,但不确定这是最好的解决方案?

这是间谍测试:

@ExtendWith(MockitoExtension.class)
class ProviderHelperServiceTest {

    @Spy
    @InjectMocks
    ProviderHelperService providerHelperService;
    
    @Value("${viaduct-url}")
    String viaductUrl;
    
    @Test
    void testGetRequestBodyUriSpec() {
        WebClient.RequestBodyUriSpec requestBodyUriSpec = providerHelperService.getRequestBodyUriSpec("sifToken");
        
        final String[] url = new String[1];
        requestBodyUriSpec.attributes(httpHeaders -> {
            url[0] = (String) httpHeaders.get("org.springframework.web.reactive.function.client.WebClient.uriTemplate");
        });

        // Fails as url[0] comes back as null. Disabled and moved to another file.
        assertEquals(viaductUrl, url[0]);
    }
@SpringBootTest
class ProviderHelperService2Test {

    @Autowired
    ProviderHelperService providerHelperService;

    @Value("${viaduct-url}")
    String viaductUrl;

    @Test
    void testGetRequestBodyUriSpec() {

        WebClient.RequestBodyUriSpec requestBodyUriSpec = providerHelperService.getRequestBodyUriSpec("sifToken");
        
        final String[] url = new String[1];
        requestBodyUriSpec.attributes(httpHeaders -> {
            url[0] = (String) httpHeaders.get("org.springframework.web.reactive.function.client.WebClient.uriTemplate");
        });

       assertEquals(viaductUrl, url[0]);
    }
}

下面是正在测试的方法:

public class ProviderHelperService {

    @Value("${viaduct-url}")
    String viaductUrl;
    
    
    public WebClient.RequestBodyUriSpec getRequestBodyUriSpec(String sifToken) {
        WebClient.RequestBodyUriSpec requestBodyUriSpec = WebClient.create().post();
        requestBodyUriSpec.header("Authorization", sifToken);
        requestBodyUriSpec.uri(viaductUrl);
        return requestBodyUriSpec;
    }

}

执行此类测试的最简洁方法是用构造函数注入替换字段注入,然后您可以很容易地确认传递到 class 的值从服务调用返回。

如果您使用的是 Boot,通常最好将 @Value 的使用替换为 @ConfigurationProperties。根据具体情况,您可以将整个属性对象传递给服务的构造函数,或者编写一个 @Bean 配置方法来解压缩相关属性并将它们作为普通构造函数参数传递给 new.