Junit with new Date()

旧街凉风 提交于 2019-12-12 10:37:24

问题


What would the junit test be when i have the following method:

@Override
public void saveLastSuccesfullLogin(final User user) {
    gebruiker.setLastLogin(new Date());
    storeUser(user);
}

submethode storeUser:

@Override
public void storeUser(final User user) {
    EntityManager em = emf.createEntityManager();

    em.getTransaction().begin();
    em.merge(user);
    em.getTransaction().commit();

    em.close();
}

The problem i have is the date, being set for the entity user and then stored. Im using junit and easymock.


回答1:


Try pulling the new Date() into a method with default access specifier like below

@Override
public void saveLastSuccesfullLogin(final User user) {
    gebruiker.setLastLogin(getDate());
    storeUser(user);
}
Date getDate() {
    return new Date();
}

In your test class override the class as below using a mock or stubbed date.

<ClassUnderTest> classUnderTest = new <ClassUnderTest> () {
  @Override 
  Date getDate() {
    return mockDate;
  } 
}

In this way you can assert the date value easily as it is going to be stubbed out.




回答2:


What's the problem with the Date? That you don't know what it is to assert later? A few alternatives:

  1. Pass the date into the method
  2. Create a factory to get the current date/time so you can mock it out
  3. Assert the date within a threshold of correctness



回答3:


There is also a more "enterprise" approach that may be used where Dependency Injection is available (like in EJB, Spring etc.).

You can define an interface, for example TimeService and add e method that returns the current date.

  public interface TimeService {
    Date getCurrentDate();
  }

You can implement this to return new Date() and use it like this:

  gebruiker.setLastLogin(timeService.getCurrentTime());

This will obviously be very easy to test because you can mock the TimeService. Using EasyMock (just an example), this might be:

  Date relevantDateForTest = ...
  expect(timeService.getCurrentTime()).andReturn(relevantDateForTest);
  replay(timeService);

Using the TimeService throughout the entire code and never using new Date() is a pretty good practice and has other advantages as well. I found it helpful in a number of occasions, including manual functional testing of features that would activate in the future. Going even further, the system time may be retrieved from an external system thus making it consistent across clusters etc.




回答4:


You can also create a getDate method, and a date static var:

    private static Date thisDate = null;

    @Override
    public void saveLastSuccesfullLogin(final User user) {
        gebruiker.setLastLogin(getDate());
        storeUser(user);
    }

    public Date getDate() {
        if(thisDate != null) return thisDate;
        return new Date();
    }

    public void setDate(Date newDate) {
        thisDate = newDate;
    }

Then in your test method, you can go ahead and call setDate to control what date you will get.



来源:https://stackoverflow.com/questions/5092017/junit-with-new-date

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