You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将含日期计算的字符串解析为日期对象?Cucumber测试技术问询

Solution for Parsing Flexible Date Offsets in Cucumber + WireMock Tests

First off, your current implementation is a solid start—let’s build on it to support all time units (minutes, hours, months, etc.) without reinventing the wheel. The key here is leaning into a battle-tested date library that natively handles relative time calculations, which will save you from writing custom regex logic for every possible unit.

Step 1: Use a Robust Date Library (Moment.js or Day.js)

Both libraries support all common time units (minutes, hours, days, months, etc.) out of the box. If you’re looking for something lighter, Day.js is a great drop-in replacement for Moment.js. For this example, we’ll stick with Moment.js since you’re already familiar with its API.

Step 2: Update Your String Replacement Logic

Modify your regex to capture the optional time unit (defaulting to days for backward compatibility) and adjust the replacement function to use that unit dynamically:

function stringReplaceNow(string) {
  // Updated regex to capture format, offset sign/amount, and optional time unit
  var regex = /<now:([A-Z0-9-]+):?((\+|-)([0-9]+)):?([a-z]+)?>/gi;
  return string.replace(regex, function (match, format, shouldModify, modification, modAmount, unit) {
    // Fallback to 'days' if no unit is specified (keeps old syntax working)
    const timeUnit = unit || 'days';
    let date = moment();
    
    if (modification === '+') {
      date = date.add(modAmount, timeUnit);
    } else if (modification === '-') {
      date = date.subtract(modAmount, timeUnit);
    }
    
    return date.format(format);
  });
}

Updated Cucumber Table Example

Now you can use any supported time unit in your feature files:

NameDatetimeState
Johnson<now:DD-MM-YYYY:-2>Processing
Minter<now:HH:mm:ss:+15:minutes>Processing
Brown<now:YYYY-MM-DD:+1:months>Done

Step 3: Handle WireMock’s {{now offset='+15 minutes'}} Format

To validate dates returned by WireMock, you’ll need to parse its offset syntax and compute the expected datetime. Here’s a helper function to do that:

function parseWireMockNowOffset(offsetStr) {
  // Match patterns like "+15 minutes", "-3 days"
  const offsetRegex = /([+-])(\d+) (\w+)/;
  const matches = offsetStr.match(offsetRegex);
  
  if (!matches) throw new Error(`Invalid offset format: ${offsetStr}`);
  
  const [, sign, amount, unit] = matches;
  let date = moment();
  
  if (sign === '+') {
    date = date.add(parseInt(amount), unit);
  } else {
    date = date.subtract(parseInt(amount), unit);
  }
  
  return date;
}

// Usage example: Calculate expected datetime from WireMock's offset
const wireMockOffset = "+15 minutes";
const expectedDatetime = parseWireMockNowOffset(wireMockOffset).format("YYYY-MM-DDTHH:mm:ss");

Step 4: Validate Datetime Accuracy and Sorting

Accuracy Check

When verifying WireMock’s response, compare the returned datetime to your computed expected value. Allow a small tolerance (e.g., 1 second) to account for test execution delay:

const actualDatetime = moment(response.body.datetime);
const expectedDatetime = parseWireMockNowOffset("+15 minutes");

// Ensure actual time is within 1 second of the expected value
expect(actualDatetime.diff(expectedDatetime, 'seconds')).toBeLessThanOrEqual(1);

Sorting Validation

To confirm your table is sorted correctly, convert all datetimes to timestamps and check the order:

// Extract items from the response and sort them by datetime
const sortedItems = [...response.body.items].sort((a, b) => 
  moment(a.datetime).valueOf() - moment(b.datetime).valueOf()
);

// Verify the original response matches the sorted order
expect(response.body.items).toEqual(sortedItems);

Alternative: Use Native Date APIs (If You Avoid Libraries)

If you don’t want to add a dependency, you can use JavaScript’s native Date object with helper functions for relative time. Note that this requires more code to handle edge cases like month rollovers:

function addRelativeTime(date, amount, unit) {
  const newDate = new Date(date);
  switch(unit) {
    case 'minutes': newDate.setMinutes(newDate.getMinutes() + amount); break;
    case 'hours': newDate.setHours(newDate.getHours() + amount); break;
    case 'days': newDate.setDate(newDate.getDate() + amount); break;
    case 'months': newDate.setMonth(newDate.getMonth() + amount); break;
    default: throw new Error(`Unsupported unit: ${unit}`);
  }
  return newDate;
}

Libraries like Moment/Day.js handle these edge cases automatically, which is a big win for test reliability.

内容的提问来源于stack exchange,提问作者Appernicus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 08:58:11