繁体   English   中英

如何在 Spring Boot 中注入 Clock.getInstance()?

[英]How to Inject Clock.getInstance() in Spring Boot?

我想对一些调用System.currentTimeMillis()代码进行单元测试。 正如这个答案指出的那样,一个很好的方法是用Clock.getInstance().currentTimeMillis()替换对System.currentTimeMillis()调用。 然后,您可以对Clock.getInstance()执行依赖注入,例如在单元测试中用模拟替换它。

所以,我的问题是对此的跟进。 你如何配置Spring Boot在运行时注入Clock.getInstance()

如果可能,我更愿意使用注释而不是 XML 来做到这一点。

另外,如果可能的话,我想这样做,我可以简单地使用@Mock@InjectMocksMockitoJUnitRunner将模拟时钟注入单元测试。

在您的配置类中,您可以执行以下操作:

@Configuration
public class Config { 
    @Bean
    public Clock clock() { 
        return Clock.fixed(...);
    } 
} 

在你的课堂上,你可以@Autowire它:

public class ClockUser {

private Clock clock;

    public ClockUser(Clock clock, ...) {
        this.clock = clock;
    }
}

(请注意,我在这里使用了构造函数注入,请参阅本文标题为基于构造函数或基于 setter 的 DI 的部分Oliver Gierke 的评论(即 Spring Data 项目负责人)以及google以获取更多信息。)

然后你可以在另一个测试@Configuration类或你的JUnit测试中创建你的模拟:

@Bean
public Clock {
    Clock clock = Mockito.mock(Clock.class);
    .... ("when" rules)
    return clock;
} 

它可以在单元测试中不使用模拟来完成。

在您的 Spring 应用程序设置中,只需添加以下内容。 它可以在您的@SpringBootApplication@Configuration

  @Bean
  public Clock clock() {
    return Clock.systemDefaultZone();
  }

这将确保您的生产代码中有一个正在运行的时钟。

对于您的测试设置,您可以选择将相同的 Clock bean 添加到您的测试配置中。 这将使不依赖于特定时间的测试无需修改即可运行。

当您有一个需要依赖特定时间的测试用例时,您只需通过在测试用例中添加以下作为内部类来覆盖测试配置。

@RunWith(SpringRunner.class)
@SpringBootTest
public class YourServiceTest {

  @Autowired
  private YourService yourService;

  ...

  @TestConfiguration
  public static class Config {
    @Bean
    public Clock clock() {
      return Clock.fixed(Instant.parse("2021-09-10T12:00:00Z"), ZoneOffset.UTC);
    }
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM