当前位置: 首页 > 知识库问答 >
问题:

SpringBoot单元测试中的Mock@Value不起作用

梁嘉澍
2023-03-14

我正在尝试使用Mockito在SprinBoot应用程序中进行一些jUnit测试。

现在我的服务有了一些变量,可以从应用程序中填充。属性通过@Value注释:

@Component
@Slf4j
public class FeatureFlagService {

  @Autowired
  RestTemplate restTemplate;

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

// do stuff
}

我试图通过像这样使用测试属性源代码来测试这个:

@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

这方面有很多TPOIC,但我还没能拼凑出一个解决方案。我看到解决方案建议@SpringBootTest,但它似乎想做一个集成测试,使服务加速,但由于无法连接到数据库,服务失败了。所以这不是我想要的。

我还看到一些解决方案建议我制作一个propertySourcesplaceConfigurerbean。我试着这样做:

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

在我的Application.java中。但这还不够。我不确定我是否应该以不同的方式做这件事,或者是否还有更多我不知道的事情。

请指教。

共有2个答案

宰父远
2023-03-14

我建议你试试这种方法。只需稍微进行重构,并向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
}

然后准备mock和url,并通过构造函数注入注入它们。

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的魔法注释了。

颜黎昕
2023-03-14

通过将包含@Value的类传递给整个应用程序,您可以使用@springbootest而无需运行整个应用程序,但是您必须使用Spring的扩展@extendedwith({SpringExtension.class}),该扩展包含在@springbootest中,并使用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");
  }
 类似资料:
  • 问题内容: 我已经通过两种方式为我的单元测试创​​建了用户: 1)为“ auth.user”创建一个大致如下的灯具: 我省去了看似不重要的部分。 2)在setUp函数中使用“ create_user”(尽管我宁愿将所有内容保留在我的Fixture类中): 请注意,两种情况下的密码均为辛普森。 我已验证该信息一次又一次正确地加载到测试数据库中。我可以使用User.objects.get来获取User

  • 我目前正在与CDI Unit合作一个项目,我遇到了一个奇怪的问题。我试图在一个简单的项目中重现它: 我有一个使用CdiRunner运行的测试类(如下所述:http://jglue.org/cdi-unit-user-guide/我的测试类注入了被测试的单元:UUD。这个类扩展了一个超级类“ParentTestClass”,它目前是无用的。 测试课。爪哇: 正如我提到的,父类是空的。 ParentT

  • 问题内容: 我正在尝试在python单元测试中模拟常量。 我有一个名为 settings.py 的模块,其中包含一组常量,特别是我有一个: 然后在另一个模块中,我有一个使用REL_PATH变量的函数,如下所示: 在我的单元测试中,我有以下代码: 我希望通过这种方式将在“另一个/自定义/路径/”路径下创建csv文件,但仍在原始目录中创建csv文件。 我也试图这样做: 但最终结果是相同的。 我究竟做错

  • 我正在尝试使用intellij idea运行单个spock单元测试。 考虑: 在上面的测试中,当我转到测试主体和右上下文菜单时,我得到了两种类型的测试。一个是grails测试,另一个是junit测试。 关于这个问题,公认的答案建议使用jUnit运行程序。但是使用它,代码根本无法编译(可能是因为某些插件和其他类不可用)。 (我不确定,因为这是期望的行为,因为我只是运行一个测试,而不是所有的测试。所以

  • 我对SonarRunner有以下问题。 SonarQube 以及 Sonar 运行器无法拉取 junit 格式的 xml 报告 “单元测试”或“测试覆盖率”小组件不显示。它说没有数据。我正在按照此处描述的说明进行操作 我按照描述手动创建了XML格式的报告文件,但是仍然没有成功。 下面是 XML 文件 - TEST-Firefox_210_Mac_OS.com.company.BarTest.xml

  • 需要对项目的控制器部分进行单元测试,但却得到了错误。我相信ModelAndVIew部分导致了这个问题,尽管我曾经嘲弄过它并返回ModelAndVIew,因为它是方法的返回类型。然而,它并不起作用。pom.xml没有任何问题,因此没有添加它。ProjectController: java.lang.IllegalStateException:找不到@SpringBootConfiguration,您