如何伪造 java.time.LocalDate 返回的日期?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29038609/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 14:34:34  来源:igfitidea点击:

How can I fake the date returned by java.time.LocalDate?

java

提问by Pétur Ingi Egilsson

I need to be able to fake the system time when testing. The source I have makes use of java.time.LocalDate. Is there a way to make LocalDate.now()return a pre-set date?

我需要能够在测试时伪造系统时间。我使用的源代码是 java.time.LocalDate。有没有办法让LocalDate.now()返回一个预设的日期?

回答by Rohit Jain

There are a few options you've:

您有几个选择:

  1. Wrap the LocalDate.now()call in a non-static method of a class. Then you can mock that method to return your specific instance - This would not seem practical if you're directly calling LocalDate.now()method at many places in your code.

  2. Use LocalDate.now(Clock)method, that is pretty test-friendly, as already suggested in comments - again you've to modify your application code.

  3. Use Powermockito, if you can. In that case, you've a pretty easy approach by mocking static methods using mockStatic(Class<?>)method.

  1. LocalDate.now()调用包装在类的非静态方法中。然后您可以模拟该方法以返回您的特定实例 - 如果您LocalDate.now()在代码中的许多地方直接调用方法,这似乎不切实际。

  2. 使用LocalDate.now(Clock)方法,这对测试非常友好,正如评论中已经建议的那样 - 您必须再次修改应用程序代码。

  3. Powermockito如果可以,请使用。在这种情况下,通过使用 method.mock 模拟静态方法,您有一个非常简单的mockStatic(Class<?>)方法。

The 3rd approach can be implemented as:

第三种方法可以实现为:

@PrepareForTest({ LocalDate.class })
@RunWith(PowerMockRunner.class)
public class DateTest {
    @Test
    public void yourTest() {
        PowerMockito.mockStatic(LocalDate.class);
        when(LocalDate.now()).thenReturn(yourLocalDateObj);
    }
}

回答by Garrett Hall

Can you dependency inject the time through the constructor / parameter of the code?

你可以通过代码的构造函数/参数依赖注入时间吗?

Otherwise you can wrap LocalDate.now() in a static class that lets you hard-code a value for testing.

否则,您可以将 LocalDate.now() 包装在一个静态类中,让您可以硬编码一个值进行测试。

回答by puj

I would usually suggest using Mockito, but since the method is static, you can't really mock the object.

我通常会建议使用 Mockito,但由于该方法是静态的,因此您无法真正模拟该对象。

Why not have some "DateProvider" class grab the date for you

为什么不让一些“DateProvider”类为您获取日期

public class DateProvider{
   public LocalDate getNow(){
      return LocalDate.now();
   }
}

and use it thusly:

并因此使用它:

new DateProvider().getNow();

That would make it fairly easy to test with any LocalDate return value

这将使使用任何 LocalDate 返回值进行测试变得相当容易

回答by JPRLCol

I was trying the code on this page but I noticed I should get the LocalDate instance first before to use PowerMockito as the 2 firstLines of the next code

我正在尝试此页面上的代码,但我注意到我应该先获取 LocalDate 实例,然后才能使用 PowerMockito 作为下一个代码的 2 firstLines

@Test
public void testYearOptions() throws Exception{

    LocalDate date = LocalDate.of(2015,11,12);
    PowerMockito.mockStatic(LocalDate.class);

    Mockito.when(LocalDate.now()).thenReturn(date);
    Map<String, String> semesterMap = Utilities.getYears(); //Your function where LocalDate is Uses

    assertNotNull(yearsMap.get("2015"));//your assertion

}

回答by Juan Salvador

For testing:

供测试用:

@RunWith(SpringRunner.class)
@SpringBootTest
public class DateTimeFactoryTest {
  private static final Logger log = LoggerFactory.getLogger(DateTimeFactoryTest.class);

  @MockBean
  DateTimeFactory dateTimeFactory;

  @Test
  public void test001() throws MissingMethodInvocationException {
    given(dateTimeFactory.getLocalDate()).willReturn(LocalDate.of(2017,4, 4));
    LocalDate ld = dateTimeFactory.getLocalDate();
  }
}

回答by Francesco Menzani

No need of spaghetti code here: keep it simple! Write a convenience methodand change its body to meet your needs.

这里不需要意大利面条式代码:保持简单!编写一个方便的方法并更改其主体以满足您的需求。

public static LocalDate getCurrentTime() {
    // You can comment right code to save it during debugging
}