web-dev-qa-db-ja.com

Springでのテスト目的でJava.time.Clockを抽象化する方法

質問に関して質問があります 時間依存の単体テスト

サービスインターフェースとその実装を含むSpringアプリケーションを構築するとしましょう

テストで時計を変更したい場合は、製品コードを「汚染」し、たとえば次のようにインターフェースする必要があります。 setClockメソッドは次のとおりです。

public interface MyService {
    void heavyBusinessLogic();
    void setClock(Clock clock);
}

@Service
public class MyServiceImpl implements MyService {

    private Clock clock = Clock.systemDefaultZone();

    @Override
    public void heavyBusinessLogic() {
        if (LocalDate.now(clock)...) {
            ... 
        }
    }

    @Override
    public void setClock(Clock clock) {
        this.clock = clock;
    }
}   

テストでは、次のように呼び出すことができます。

service.setClock(Clock.fixed(Instant.parse("2017-02-14T01:22:00Z"), ZoneOffset.UTC));

春にこのような横断的関心事をどのように抽象化できますか?

Java.time.Clockを使い続けたい(Jodaは使いたくない)

8

個人的には、コンストラクターに時計を追加するだけです...

public MyServiceImpl(Clock clock) {
  this.clock = clock;
}

...そしておそらくNiceのデフォルトコンストラクタを追加します...

public MyServiceImpl() {
  this(Clock.systemDefaultZone());
}

このようにして、Springを介してデフォルトのものを取得し、たとえばテストでカスタムクロックバージョンを手動で作成できます。

もちろん、デフォルトのコンストラクターを使用せずに、たとえば次のように、実稼働構成にClockBeanを追加することもできます...

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

...これにより、モックされたClockをテスト構成のBeanとして使用できるようになり、Springが自動的に@Autowireコンストラクタインジェクションを介して。

14
Florian Schaetz