How to test date created with LocalDateTime.now()

…衆ロ難τιáo~ 提交于 2020-12-30 06:15:49

问题


I have this class

class MyObject {
    private LocalDateTime date;

    public LocalDateTime getDate() { return this.date; }

    public void myMethod() {
        this.date = LocalDateTime.now();
    }
}

How can I test that the date is properly set? I cannot mock now() because it is static and if I used LocalDateTime in the test both dates won't be the same.


回答1:


You could generate a date time just before calling myMethod() and make sure that this date is before or equals to the date returned by getDate(), something like that:

@Test
public void testDate() {
    MyObject object = new MyObject();
    // Get the current date time 
    LocalDateTime time = LocalDateTime.now();
    // Affect the current date time to the field date
    object.myMethod();
    // Make sure that it is before or equals
    Assert.assertTrue(time.isBefore(object.getDate()) || time.isEqual(object.getDate()));
}

If you don't care adding coupling to your class a better approach could be to provide a Supplier<LocalDateTime> to your class as next:

public class MyObject {
    private final Supplier<LocalDateTime> supplier;
    private LocalDateTime date;

    public MyObject() {
        this(LocalDateTime::now);
    }

    public MyObject(final Supplier<LocalDateTime> supplier) {
        this.supplier = supplier;
    }

    public LocalDateTime getDate() { return this.date; }

    public void myMethod() {
        this.date = supplier.get();
    }
}

This way it will be easy to create a Supplier for testing purpose in your test case.

For example the test case could then be:

@Test
public void testDate() {
    LocalDateTime time = LocalDateTime.now();
    MyObject object = new MyObject(() -> time);
    object.myMethod();
    Assert.assertTrue(time.isEqual(object.getDate()));
}



回答2:


I cannot mock now() because it is static

Indeed - but fortunately, you don't have to. Instead, consider "a date/time provider" as a dependency, and inject that as normal. java.time provides just such a dependency: java.time.Clock. In tests you can provide a fixed clock via Clock.fixed(...) (no mocking required) and for production you'd use Clock.system(...).

Then you change your code to something like:

class MyObject {
    private final Clock clock;
    private LocalDateTime date;

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

    public LocalDateTime getDate() {
        return this.date;
    }

    public void myMethod() {
        this.date = LocalDateTime.now(clock);
    }
}

... or however you normally deal with dependencies.




回答3:


Update your class as below :

class MyObject {
    private LocalDateTime date;

    public Supplier<LocalDateTime> localDateTime = ()-> LocalDateTime.now();

    public LocalDateTime getDate() { return this.date; }

    public void myMethod() {
        this.date = localDateTime.get();
    }
}

and in the test method update the supplier variable as below just before calling myMethod:

objMyObject.localDateTime = ()-> LocalDateTime.parse("2020-11-24T23:59:59.999");


来源:https://stackoverflow.com/questions/39527752/how-to-test-date-created-with-localdatetime-now

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!