Readable unit testing for local timezone using dayjs
Unit testing is a crucial aspect of software development, and when it comes to testing functionality dependent on time and timezones, having readable and effective tests is essential.
In this blog post, we'll explore how to perform unit testing for local timezones using TypeScript and Dayjs
. We'll walk through a practical example involving a function to identify the state of a resource based on its environment and the current time. Additionally, we'll introduce a Dayjs
timezone helper to facilitate seamless testing across different timezones.
Example Code
Let's start by examining the core function responsible for identifying the state of a resource:
export function identifyResourceState(
resource: { env: string },
date: Date = new Date()
): 'scaled_up' | 'scaled_down' {
if (resource.env !== 'dev') {
return 'scaled_up';
}
const hour = date.getUTCHours();
if (hour >= 1 && hour <= 12) {
return 'scaled_up';
}
return 'scaled_down';
}
Dayjs Timezone helper
To enhance the testing process, we introduce a Dayjs helper to handle timezones effectively:
import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
dayjs.extend(utc)
dayjs.extend(timezone)
export function createDateFromTimezone(date?: dayjs.ConfigType, timezone?: string) {
return (date?: dayjs.ConfigType) => dayjsFromTimezone(date, timezone).toDate();
}
export function dayjsFromTimezone(date?: dayjs.ConfigType, timezone?: string) {
return dayjs.tz(date, timezone).utc();
}
Implementation
Now, let's look at how we can effectively test the identifyResourceState
function using our Dayjs timezone helpe
import { expect, test } from 'vitest';
import { createDateFromTimezone } from './dayjs';
import { identifyResourceState } from './identify-resource-state';
const createBangkokDate = createDateFromTimezone('Asia/Bangkok');
const dateString = '2023-12-15';
test('identifyResourceState for dev', () => {
expect(identifyResourceState({ env: 'dev' }, createBangkokDate(`${dateString} 06:00`))).toBe('scaled_down');
expect(identifyResourceState({ env: 'dev' }, createBangkokDate(`${dateString} 09:00`))).toBe('scaled_up');
expect(identifyResourceState({ env: 'dev' }, createBangkokDate(`${dateString} 12:00`))).toBe('scaled_up');
expect(identifyResourceState({ env: 'dev' }, createBangkokDate(`${dateString} 20:00`))).toBe('scaled_down');
});
test('identifyResourceState for prod', () => {
expect(identifyResourceState({ env: 'prod' }, createBangkokDate(`${dateString} 06:00`))).toBe('scaled_up');
expect(identifyResourceState({ env: 'prod' }, createBangkokDate(`${dateString} 09:00`))).toBe('scaled_up');
expect(identifyResourceState({ env: 'prod' }, createBangkokDate(`${dateString} 12:00`))).toBe('scaled_up');
expect(identifyResourceState({ env: 'prod' }, createBangkokDate(`${dateString} 20:00`))).toBe('scaled_up');
});
In this example, we've provided a clear introduction, added comments, and organized the content for better readability. Feel free to adapt this to suit your preferences and context!