测试静态函数的最佳方法,检查它是否是该月的第一个星期一 (Typescript/Angular/Jasmin)

Best way to test static function checking whether it is the first monday of the month or not (Typescript/Angular/Jasmin)

我有以下功能来检查是否是该月的第一个星期一。 该函数处于静态 class Validation.ts

public static isFirstMondayOfMonth(): boolean {
  const d = new Date();
  const currentMonth = d.getMonth();

  // if it is monday
  if (d.getDay() === 1) {
    // Then check if we are still in the same month if we go 7 days back in time. If we're not, then it is the first monday
    d.setDate(d.getDate() - 7);
    if (currentMonth !== d.getMonth()) {
      return true;
    }
  }

  return false;
}

我如何测试此功能是否按预期工作?现在我的测试用例只有当它实际上是该月的第一个星期一时才会通过。什么是更好的测试方法?

it('Should be true if first monday of the month',() => {
  expect(Validations.isFirstMondayOfMonth()).toBeTruthy();
})

A deterministic function always returns the same results if given the same input values. A non-deterministic function may return different results every time it is called, even when the same input values are provided.

isFirstMondayOfMonth() 是一个非确定性函数。根据调用日期不同,它可能会产生不同的结果。因此,它不能按原样进行单元测试。

我建议将其转换为确定性函数(也称为 pure function),如下所示;

public static isFirstMondayOfMonth(date: Date): boolean {
  const d = new Date(date.getTime()); // clone the input argument for immutability
  const currentMonth = d.getMonth();

  // if it is monday
  if (d.getDay() === 1) {
    // Then check if we are still in the same month if we go 7 days back in time. If we're not, then it is the first monday
    d.setDate(d.getDate() - 7);
    if (currentMonth !== d.getMonth()) {
      return true;
    }
  }

  return false;
}

然后进行相应的测试;

it('Should be true if first monday of the month',() => {
  const d1 = new Date(2020, 4, 4); // first monday of May, 2020
  expect(Validations.isFirstMondayOfMonth(d1)).toBeTruthy();

  const d2 = new Date(2020, 4, 11); // second monday of May, 2020
  expect(Validations.isFirstMondayOfMonth(d2)).toBeFalsy();
})